我在Linux上(Ubuntu 12.04,gcc 4.6.3),試圖彎曲dlopen /接近我的意志,以便製作一個基於插件的應用程序,可以在必要時重新加載插件(例如,如果它們是重新編譯)。如何知道過程是否真正完成了dlclose()庫?
基本理論很簡單:dlopen插件;使用它,跟蹤所有正在使用的符號。當需要重新加載時,清理所有符號並關閉插件。
我一起扔一個簡單的演示應用程序,「TEST.CPP」:
#include <dlfcn.h>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
if (argc > 1)
{
void* h = dlopen(argv[1], RTLD_NOW|RTLD_LOCAL);
if (!h)
{
cerr << "ERROR: " << dlerror() << endl;
return 1;
}
cin.get();
if (dlclose(h))
{
cerr << "ERROR: " << dlerror() << endl;
return 2;
}
cin.get();
}
return 0;
}
編譯:
g++ test.cpp -o test -ldl
爲了可以作爲參數傳遞到上面的一個簡單的圖書館代碼,使用:
:touch libtest.cpp && g++ -rdynamic -shared libtest.cpp -o libtest.so
然後運行
./test ./libtest.so
這是問題;如果在按[Enter]一次後(即加載並假定卸載庫之後),則運行'pmap'以檢查在'test'中加載了哪些庫,它會告訴你libtest.so仍然存在!現在這是儘管從dlclose()有效返回,並沒有合理的方式,引用計數可以在此之前微升到1以上(這可以通過嘗試第二個dlclose()來驗證 - 它會給出錯誤返回,說它已經是關閉)。
因此,無論是Linux 從來沒有卸載dlopen()ed庫(違反文檔),或'pmap'是錯誤的。如果是後者,是否有更可靠的方法來確定庫是否仍然被加載?