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

我用于构建共享库的命令行看起来像:

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

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

但是,我无法访问可执行文件本身中的(导出)功能(我得到 undefined symbol 错误)。

我的电话 dlopen 看起来这样:

void *handle = dlopen(plugin, RTLD_NOW);

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

有帮助吗?

解决方案 2

我自己找到了答案。

我不得不添加 --export-dynamic 标记为主要可执行文件的链接选项。

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

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

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

其他提示

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

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

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

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

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

a)您的程序(或TRIRD PARTY模块)与共享库相连(不在运行时),该库需要在动态表中;

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top