如何在未与其直接连接的其他库中调用库函数?

use*_*893 6 c gcc shared-libraries

这是我的例子,我有main.c,dlopens lib1.so和链接lib2.so时链接. lib1.so需要调用一个定义的函数lib2.so,如下所示:

main.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;
}
Run Code Online (Sandbox Code Playgroud)


lib1.c

extern void func2();

void func1(){
    printf("Function1\n");
    func2();
}
Run Code Online (Sandbox Code Playgroud)


lib2.c

void func2(){
    printf("Function2\n");
}
Run Code Online (Sandbox Code Playgroud)


我以前编译主要是悲伤的

gcc -rdynamic main.c -o main lib2.so -ldl
Run Code Online (Sandbox Code Playgroud)

但是当我跑main我得到的undefined symbol: lib2,但如果我删除评论//func2()中的main.c(所以我简单地调用func2()至少一次main),程序工作,并lib1可以调用func2().
为什么我不能func2()lib1没有打电话的情况下打电话给你main,有什么方法可以避免这种情况吗?

yug*_*ugr 3

发生这种情况是因为所有现代 Linux 发行版中默认启用了--as-needed链接器选项。链接器意识到主模块不使用任何内容lib2.so并忽略-llib2选项。要强制lib2.so链接,您可以插入对其功能之一的虚假引用(如您所建议的),或者--as-needed在链接时简单地禁用lib2.so

gcc ... -Wl,--no-as-needed lib2.so -Wl,--as-needed
Run Code Online (Sandbox Code Playgroud)

另一个有意义的解决方案是链接lib1.solib2.so.