Как я могу вызвать библиотечную функцию в другой библиотеке, не связанной напрямую с ней? - PullRequest
0 голосов
/ 28 августа 2018

Это мой пример, у меня есть main.c, это dlopen s 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;
}


lib1.c

extern void func2();

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


lib2.c

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, не позвонив также и в main, есть ли способ избежать этого?

1 Ответ

0 голосов
/ 28 августа 2018

Это происходит из-за - при необходимости опция компоновщика включена по умолчанию во всех современных дистрибутивах Linux. Линкер понимает, что основной модуль не использует ничего из lib2.so, и игнорирует параметр -llib2. Для принудительного связывания lib2.so вы можете либо вставить поддельную ссылку на одну из ее функций (как вы предлагали), либо просто отключить --as-needed при связывании lib2.so:

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

Другим значимым решением было бы связать lib1.so с lib2.so.

...