C:处理共享对象中的未定义符号

时间:2016-12-02 13:21:29

标签: c gcc dlopen undefined-symbol

我与dlopen未定义的符号挣扎。

到目前为止我所拥有和尝试的内容:

libraryA.a ,功能为functionA()

带有函数functionA()

libraryA.so 使用functionA()

libraryB.so

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

我得到的是:

undefined symbol: functionA

我如何建立:

LibraryA的:

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

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/ 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标志但也没有成功。

有人可以帮助我吗?

3 个答案:

答案 0 :(得分:1)

您需要将libraryB.solibraryA.so相关联,因为libraryB.so使用libraryA.so中的符号。

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

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

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

答案 1 :(得分:0)

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

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

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

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

否则,您仍然可以使用libarryB.so检查ldd以查看它引用的库。

答案 2 :(得分:-1)

<强>解决方案

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,之后一切都很好,我可以使用所有符号和函数。

非常感谢你们所有人!