【发布时间】:2012-06-14 21:32:02
【问题描述】:
我在 Linux (Ubuntu 12.04, gcc 4.6.3) 上,试图弯曲 dlopen/close 以创建一个基于插件的应用程序,该应用程序可以在必要时重新加载其插件(例如,如果他们'重新编译)。
基本原理很简单: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”以检查在“测试”中加载了哪些库,它会告诉您 libtest.so 仍然存在!现在,尽管 dlclose() 有一个有效的返回,并且没有合理的方式使引用计数在此之前超过 1(这可以通过尝试第二个 dlclose() 来验证 - 它会给出一个错误返回,说明它已经关闭)。
因此,要么 Linux 从不 卸载 dlopen() ed 库(与文档相矛盾),要么 'pmap' 是错误的。如果是后者,有没有更可靠的方法来判断一个库是否还在加载?
【问题讨论】:
标签: c++ linux plugins g++ dlopen