23

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

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

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

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

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

我的电话dlopen看起来像这样:

void *handle = dlopen(plugin, RTLD_NOW);

谁能告诉我的模块如何回调我的可执行文件,而不必将所有可执行文件的实用程序功能放入另一个共享库中?

4

3 回答 3

35

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

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

于 2009-01-27T07:31:38.367 回答
8

我自己找到了答案。

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

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

如果您不使用此选项,动态符号表通常将仅包含链接中提到的某个动态对象引用的那些符号。

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

于 2009-01-26T17:40:38.717 回答
4

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

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

我认为解决方案更好。原因是,如果你也解决了同样的问题

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

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

于 2009-08-30T18:47:34.363 回答