2014-08-27 3 views
2

Я пытаюсь разрешить общей библиотеке вызывать функцию из процесса, в который она загружается. Библиотека написана на C, «ядре» на C++.dlopen can not find demangled symbols

kernel.cpp:

#include <stdio.h> 
#include <dlfcn.h> 

typedef void(*func_t)(); 

extern "C" { 
     void test(); 
} 

int main() { 
     char *error; 
     void *handle = dlopen("./library.so", RTLD_LAZY); 
     if((error = dlerror()) != NULL) { 
       fprintf(stderr, "%s\n", error); 
       return 1; 
     } 
     func_t init = (func_t)dlsym(handle, "init"); 
     if((error = dlerror()) != NULL) { 
       fprintf(stderr, "%s\n", error); 
       return 1; 
     } 
     init(); 

     return 0; 
} 

void test() { 
     fprintf(stderr, "test() called.\n"); 
} 

library.c:

#include <stdio.h> 

void test(); 

void init() { 
     fprintf(stderr, "init() called.\n"); 
     test(); 
} 

Makefile:

all: 
     g++ -ldl kernel.cpp -o kernel 
     gcc -fpic -shared library.c -o library.so 
     ./kernel 

objdump -x ядро ​​

SYMBOL TABLE: 
... 
000000000040088b g  F .text 0000000000000024 test 

Запуск программы, я получаю следующий результат:

init() called. 
./kernel: symbol lookup error: ./library.so: undefined symbol: test 

Если я изменить dlopen использовать RTLD_NOW, я получаю:

./library.so: undefined symbol: test 

Почему библиотека с трудом находя, что символ, когда он явно не искалечен, сидит прямо там?

+1

Когда вы объявляете его вы говорите 'extern" C "', но когда вы его определяете, вы этого не делаете. – doctorlove

ответ

5

Символы исполняемого файла по умолчанию не экспортируются.

Вам нужен флаг компоновщика -export-динамический для связывания исполняемого:

g++ -ldl -Wl,-export-dynamic kernel.C -o kernel 

Цитирование со страницы л.д. человека, который описывает ваш точный сценарий:

If you use "dlopen" to load a dynamic object which needs to refer 
back to the symbols defined by the program, rather than some other 
dynamic object, then you will probably need to use this option when 
linking the program itself. 
+0

Вы можете просто использовать 'g ++ -Wall -rdynamic kernel.C -o kernel -ldl', поскольку' -rdynamic' совпадает с '-Wl, -export-dynamic' –

+0

. Тем не менее это ничего не решает, но на этот раз я получаю library.so: undefined symbol: init и имя файла не является ядром.C его kernel.cpp – Adarsh

+0

благодарит за помощь! Все, что мне нужно, - это все, что нужно. –