使用dlopen加载库时收到“未定义的符号”错误

时间:2009-01-26 17:29:23

标签: shared-libraries dlopen

我正在编写一些使用动态共享库作为插件的代码。

用于构建共享库的命令行如下所示:

cc -shared -fPIC -o module.so -g -Wall module.c

在模块中,我可以调用已在主可执行文件中加载的任何其他共享库中的函数。

但是我无法访问可执行文件中的(导出的)函数(我得到undefined symbol错误)。

我对dlopen的呼吁如下:

void *handle = dlopen(plugin, RTLD_NOW);

任何人都可以建议我的模块如何回调我的可执行文件,而不必将所有可执行文件的实用程序函数放入另一个共享库中?

3 个答案:

答案 0 :(得分:30)

正确的解决方案是将-rdynamic添加到主可执行文件的链接命令中。这会为ld添加适当的选项(使用GNU ld时恰好是--export-dynamic)。

直接添加--export-dynamic在技术上是不正确的:它是一个链接器选项,因此应添加为-Wl,--export-dynamic-Wl,-E。这也比-rdynamic更不便携(其他链接器具有等效的,但选项本身也不同)。

答案 1 :(得分:5)

我自己找到了答案。

我必须将--export-dynamic标志添加到主可执行文件的链接选项中。

  

创建动态链接时   可执行文件,将所有符号添加到   动态符号表。动态   符号表是符号集   从动态对象可见   在运行时。

     

如果您不使用此选项,则   动态符号表通常会   仅包含那些符号   由一些动态对象引用   在链接中提到。

     

如果使用“dlopen”加载动态   需要参考的对象   程序定义的符号,   而不是一些其他动态对象,   那么你可能需要使用   链接程序时的此选项   本身。

答案 2 :(得分:4)

当我遇到同样的问题时,我只使用了以下解决方案。在加载任何插件之前,只需加载程序本身,将其符号带到动态表:

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

我认为解决方案更好。原因是,如果你

,它也解决了同样的问题

a)您的程序(或三方模块)与共享库链接(不在运行时),这些符号需要在动态表中;

b)无法使用-rdynamic标志重新编译该模块。