Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call a library function in an other library not directly connected to it?

This is my example, I have main.c, that dlopens lib1.so and is linked to lib2.so at linking time. lib1.so needs to call a function defined in lib2.so, something like this:

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;
}


lib1.c

extern void func2();

void func1(){
    printf("Function1\n");
    func2();
}


lib2.c

void func2(){
    printf("Function2\n");
}


I compile main as I sad before

gcc -rdynamic main.c -o main lib2.so -ldl

but when I run main I get undefined symbol: lib2, but if I remove the comment //func2() in main.c (so I simply call func2() at least one time in main), the program works and lib1 is able to call func2().
Why can't I call func2() in lib1 without calling it also in main, is there any way to avoid this?

like image 710
user10207893 Avatar asked Aug 28 '18 09:08

user10207893


1 Answers

This happens due to --as-needed linker option being enabled by default in all modern Linux distros. Linker realizes that main module does not use anything from lib2.so and ignores -llib2 option. To force lib2.so linkage you can either insert a fake reference to one of it's functions (as you suggested) or simply disable --as-needed when linking lib2.so:

gcc ... -Wl,--no-as-needed lib2.so -Wl,--as-needed

Another meaningful solution would be to link lib1.so against lib2.so.

like image 189
yugr Avatar answered Nov 15 '22 05:11

yugr