【问题标题】:Receive "undefined symbol" error when loading library with dlopen使用 dlopen 加载库时收到“未定义符号”错误
【发布时间】:2010-10-03 14:19:15
【问题描述】:

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

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

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

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

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

我对@9​​87654323@ 的调用如下所示:

void *handle = dlopen(plugin, RTLD_NOW);

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

【问题讨论】:

    标签: shared-libraries dlopen


    【解决方案1】:

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

    直接添加--export-dynamic 在技术上是不正确的:它是一个链接器选项,因此应添加为-Wl,--export-dynamic 或-Wl,-E。这也比-rdynamic 的可移植性差(其他链接器也有类似的,但选项本身不同)。

    【讨论】:

    • 此解决方案也适用于使用 Boost Extensions 时,因为 boost shared_library 类使用 dlopen(在 Linux 上)加载库。
    【解决方案2】:

    我自己找到了答案。

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);
      

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

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

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

      【讨论】:

        猜你喜欢
        • 2012-01-11
        • 2012-09-27
        • 2012-10-10
        • 1970-01-01
        • 2021-03-08
        • 2013-01-15
        • 2018-03-19
        • 1970-01-01
        相关资源
        最近更新 更多