【问题标题】:C: Handle undefined symbols in shared objectC:处理共享对象中未定义的符号
【发布时间】:2016-12-05 19:17:21
【问题描述】:

我一直在为dlopen未定义的符号而苦恼。

到目前为止我已经尝试过的:

libraryA.a 带有函数functionA()

libraryA.so 带有函数functionA()

libraryB.so 正在使用functionA()

使用 dlopen 加载 libraryB.so 的可执行文件。

我得到的是:

undefined symbol: functionA

我如何构建:

图书馆A:

gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror
-fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables      
-fno-stack-protector -I../include/ libraryA.c -shared -o libraryA.so

图书馆B:

gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color 
-fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables 
-fno-stack-protector -I../include/ libraryB.c -shared -o libraryB.so

构建可执行文件:

-std=gnu99 -pipe -fno-strict-aliasing -fsigned-char -fno-asynchronous-unwind-tables
-fno-stack-protector -Wall -Wextra -Wundef -Wno-sign-compare -Wno-unused-parameter
-Wno-packed-bitfield-compat -Wno-misleading-indentation -fomit-frame-pointer
-maccumulate-outgoing-args -fPIC -m64 -g3 -gdwarf-2 -fno-common -Wstrict-prototypes
-Wimplicit -Wno-pointer-sign -c executable.c -o executable libraryA.a

像这样在可执行文件中打开 libraryB:

void *handle = dlopen("libraryB.so", RTLD_LAZY);

if (handle == NULL) {
    fprintf( stderr, "Load error (%s)!\n", dlerror());
    return NULL;
}

如何解决此问题?我也尝试了标志 -rdynamic 没有成功。我也尝试了不同的 dlopen 标志,但也没有成功。

谁能帮帮我?

【问题讨论】:

    标签: c gcc dlopen undefined-symbol


    【解决方案1】:

    您需要将libraryB.solibraryA.so 链接起来,因为libraryB.so 使用来自libraryA.so 的符号。

    只需将libraryA.so 添加到libraryB.so 的链接命令即可。

    根据库的安装位置,您可能还需要使用-rpath 标志。

    此外,由于libraryB.so 依赖于libraryA.so,您的Makefile 规则应明确指定此依赖关系。

    【讨论】:

    • 这我也尝试了 -L-l 选项,但我仍然在 libraryB中有未定义的符号>
    • 仍未解决。 gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables -fno-stack-protector -I../include/ libraryA.so libraryB.c -shared -o libraryB.so
    • 1) 使用objdump -T 验证从 libraryB.so 引用的符号与 libraryA.so 中声明的符号相同,并且 libraryA.so 符号声明为全局 2) 使用 @987654334 @ 验证 libraryb.so 指定“NEEDED libraryA.so`
    • 1) libraryA.so 00000000001d7d3b g DF .text 000000000000008d Base functionA libraryB.so 0000000000000000 DF *UND* 0000000000000000 functionA 2) libraryB.so 显示没有指定 libraryA.so 我有什么问题吗?
    • 尝试将 libraryA.so 放在 libraryB.c 之后(背景见creating-a-shared-object-which-depends-on-other-shared-objects)。
    【解决方案2】:

    在构建库 B 时,需要将其与库 A 链接:

    gcc -shared -o libraryB.so libraryB.c -lraryA
    

    如果libraryA.so 不在您的搜索路径中,您可能需要添加合适的-L 选项。

    如果库 B 旨在完整,没有未定义的符号,请将选项 -Wl,--no-undefined 添加到您的链接行。这样,任何缺少的依赖项都会在链接时报告,而不是等到运行时。

    否则,您仍然可以检查 libarryB.soldd 以查看它引用了哪些库。

    【讨论】:

      【解决方案3】:

      解决方案

      gcc -std=gnu11 -O2 -g -Wall -Wstack-usage=2000 -Werror -fdiagnostics-color -fPIC -pipe -fsigned-char -fno-asynchronous-unwind-tables -fno-stack-protector -I../include/ libraryB.c libraryA_static.a -shared -o libraryB.so
      

      我用 A 的静态库构建了我的 libraryB,之后一切正常,我可以使用所有符号和函数。

      非常感谢大家!

      【讨论】:

      • 虽然不一样 - 您现在已将 B 静态 链接到 A。您应该能够将 B 动态 链接到 A 所以它们可以独立更新。像gcc -shared -o libraryB.so libraryB.c -lraryA 这样的东西。如果您想确保满足 B 的所有要求,请添加-Wl,--no-undefined
      猜你喜欢
      • 1970-01-01
      • 2016-03-25
      • 2018-04-14
      • 2016-10-16
      • 1970-01-01
      • 2017-03-20
      • 1970-01-01
      • 1970-01-01
      • 2012-01-08
      相关资源
      最近更新 更多