这是我的示例,我有main.c
个dlopen
的{{1}},并在链接时链接到lib1.so
。
lib2.so
需要调用lib1.so
中定义的函数,如下所示:
main.c
lib2.so
lib1.c
extern void func2();
int main(){
void *handle;
void (*lib1)();
handle = dlopen("./lib1.so", RTLD_LAZY);
*(void**)(&lib1) = dlsym(handle, "lib1");
if(!lib1){
printf("Can't find lib1\n");
}
else{
func1();
dlclose(handle);
}
//func2();
return 0;
}
lib2.c
extern void func2();
void func1(){
printf("Function1\n");
func2();
}
我以前很伤心地编译main
void func2(){
printf("Function2\n");
}
但是当我运行gcc -rdynamic main.c -o main lib2.so -ldl
时,我得到main
,但是如果我在undefined symbol: lib2
中删除了注释//func2()
(因此我至少叫main.c
时间func2()
中),程序将运行,并且main
可以调用lib1
。
为什么不能在func2()
中同时调用func2()
中的lib1
,有什么办法可以避免这种情况?
答案 0 :(得分:3)
发生这种情况是由于在所有现代Linux发行版中默认启用了--as-needed链接器选项。链接器意识到主模块不使用lib2.so
中的任何内容,因此忽略了-llib2
选项。要强制进行lib2.so
链接,您可以插入对其中一个功能的虚假引用(如您建议的那样),或者在链接--as-needed
时仅禁用lib2.so
:
gcc ... -Wl,--no-as-needed lib2.so -Wl,--as-needed
另一个有意义的解决方案是将lib1.so
与lib2.so
链接。