Возникла проблема при компиляции программы, связанная с проверкой типов данных.Код:
#include<dlfcn.h>
#include<stdio.h>typedef void (*simple_demo_function)(void);
int main(void)
{
const char *error;
void *module;
simple_demo_function demo_function;
module = dlopen("libhello.so", RTLD_LAZY);
if (!module)
{
fprintf(stderr, "Couldn't open libhello.so: %s\n", error);
}dlerror();
demo_function = dlsym(module, "hello");
if ((error = dlerror()))
{
fprintf(stderr, "Couldn't find hello: %s\n", error);
}(*demo_function)();
dlclose(module);
return 0;
}Использую компилятор g++(при gcc такой ошибки не возникает, но мне необходимо использовать g++ или c++)
g++ -fPIC -g -c libhello.c
g++ -g -shared -ldl -Wl,-soname,libhello.so.0 -o libhello.so.0.0 libhello.c -lc
ln -sf libhello.so.0.0 libhello.so
g++ -g -c demo.c -o demo.o
g++ -g -o demo demo.o -L. -lhelloВыдает:
libhello.c:5:3: warning: no newline at end of file
libhello.c:5:3: warning: no newline at end of file
demo.c: In function `int main()':
demo.c:19: error: invalid conversion from `void*' to `void (*)()'
Долго парился, искал по всему инету - ничего не нашел.Помогите, плиз, если не составит труда.
Может какой-нибудь флажок поставить нужно, чтобы отключить жесткую проверку типов или еще чего-нибудь :)Заранее респект!
>Возникла проблема при компиляции программы, связанная с проверкой типов данных.
>
>Код:
>
>#include<dlfcn.h>
>#include<stdio.h>
>
>typedef void (*simple_demo_function)(void);
>
>
>int main(void)
> {
> const char *error;
> void *module;
> simple_demo_function demo_function;
> module = dlopen("libhello.so", RTLD_LAZY);
> if (!module)
> {
> fprintf(stderr, "Couldn't open libhello.so: %s\n", error);
>
> }
>
> dlerror();
> demo_function = dlsym(module, "hello");
> if ((error = dlerror()))
> {
> fprintf(stderr, "Couldn't find hello: %s\n", error);
>
> }
>
> (*demo_function)();
> dlclose(module);
> return 0;
>}
>
>Использую компилятор g++(при gcc такой ошибки не возникает, но мне необходимо использовать
>g++ или c++)
>
>g++ -fPIC -g -c libhello.c
>g++ -g -shared -ldl -Wl,-soname,libhello.so.0 -o libhello.so.0.0 libhello.c -lc
>ln -sf libhello.so.0.0 libhello.so
>g++ -g -c demo.c -o demo.o
>g++ -g -o demo demo.o -L. -lhello
>
>Выдает:
>
>libhello.c:5:3: warning: no newline at end of file
>libhello.c:5:3: warning: no newline at end of file
>demo.c: In function `int main()':
>demo.c:19: error: invalid conversion from `void*' to `void (*)()'
>
>
>Долго парился, искал по всему инету - ничего не нашел.
>
>Помогите, плиз, если не составит труда.
>Может какой-нибудь флажок поставить нужно, чтобы отключить жесткую проверку типов или еще
>чего-нибудь :)
>
>Заранее респект!
Строка:demo_function = dlsym(module, "hello");
dlsym возвщает void*, a demo_function имеет тип void(*)().
Попробуйте что-то вроде этого:
demo_function = (simple_demo_function)dlsym(module, "hello");
т.е., явно приведите тип значения возвращаемого dlsym() к simple_demo_function, может поможет.
>>Возникла проблема при компиляции программы, связанная с проверкой типов данных.
>>
>>Код:
>>
>>#include<dlfcn.h>
>>#include<stdio.h>
>>
>>typedef void (*simple_demo_function)(void);
>>
>>
>>int main(void)
>> {
>> const char *error;
>> void *module;
>> simple_demo_function demo_function;
>> module = dlopen("libhello.so", RTLD_LAZY);
>> if (!module)
>> {
>> fprintf(stderr, "Couldn't open libhello.so: %s\n", error);
>>
>> }
>>
>> dlerror();
>> demo_function = dlsym(module, "hello");
>> if ((error = dlerror()))
>> {
>> fprintf(stderr, "Couldn't find hello: %s\n", error);
>>
>> }
>>
>> (*demo_function)();
>> dlclose(module);
>> return 0;
>>}
>>
>>Использую компилятор g++(при gcc такой ошибки не возникает, но мне необходимо использовать
>>g++ или c++)
>>
>>g++ -fPIC -g -c libhello.c
>>g++ -g -shared -ldl -Wl,-soname,libhello.so.0 -o libhello.so.0.0 libhello.c -lc
>>ln -sf libhello.so.0.0 libhello.so
>>g++ -g -c demo.c -o demo.o
>>g++ -g -o demo demo.o -L. -lhello
>>
>>Выдает:
>>
>>libhello.c:5:3: warning: no newline at end of file
>>libhello.c:5:3: warning: no newline at end of file
>>demo.c: In function `int main()':
>>demo.c:19: error: invalid conversion from `void*' to `void (*)()'
>>
>>
>>Долго парился, искал по всему инету - ничего не нашел.
>>
>>Помогите, плиз, если не составит труда.
>>Может какой-нибудь флажок поставить нужно, чтобы отключить жесткую проверку типов или еще
>>чего-нибудь :)
>>
>>Заранее респект!
>
>
>Строка:
>
>demo_function = dlsym(module, "hello");
>
>dlsym возвщает void*, a demo_function имеет тип void(*)().
>
>Попробуйте что-то вроде этого:
>
>demo_function = (simple_demo_function)dlsym(module, "hello");
>
>т.е., явно приведите тип значения возвращаемого dlsym() к simple_demo_function, может поможет.
>
>
>
>К сожалению, это не помогло(ошибок компиляции нет, но появилась ошибка при выполнении программы)... хотя была надежда =(
Выдает ошибку:
Couldn't find hello: ./libhello.so.0: undefined symbol: hello
Segmentation faultЯ даже обновил gcc до последней версии ... не помогло.
Неужели ни у кого нет опыта по этому вопросу... =(Готовлю веревку и мыло :(
>
>К сожалению, это не помогло(ошибок компиляции нет, но появилась ошибка при выполнении
>программы)... хотя была надежда =(
>Выдает ошибку:
>Couldn't find hello: ./libhello.so.0: undefined symbol: hello
>Segmentation faultНу, если ошибок компиляции нет, значит в чем-то помогло :)
А новая ошибка - это уже собсем другая проблема: C++ name mangling - поскольку вы компилировали libhello как C++, реальное (видимое линкером) имя функции hello() на самом деле не "hello" а нечто иное, построенное компилятором g++ по неким правилам по которым в имени закодированы тип возвращяемого значения и типы параметров (google "g++ name mangling").
Попробуйте с помощью команды "nm" посмотреть какие имена содержит построенная библиотека libhello.so - вот такое имя и надо указать в dlsym(module, "mangled_name_of_hello").
>>
>>К сожалению, это не помогло(ошибок компиляции нет, но появилась ошибка при выполнении
>>программы)... хотя была надежда =(
>>Выдает ошибку:
>>Couldn't find hello: ./libhello.so.0: undefined symbol: hello
>>Segmentation fault
>
>Ну, если ошибок компиляции нет, значит в чем-то помогло :)
>
>А новая ошибка - это уже собсем другая проблема: C++ name mangling
>- поскольку вы компилировали libhello как C++, реальное (видимое линкером) имя
>функции hello() на самом деле не "hello" а нечто иное, построенное
>компилятором g++ по неким правилам по которым в имени закодированы тип
>возвращяемого значения и типы параметров (google "g++ name mangling").
>
>Попробуйте с помощью команды "nm" посмотреть какие имена содержит построенная библиотека libhello.so
>- вот такое имя и надо указать в dlsym(module, "mangled_name_of_hello").Огромное спасибо!
Действительно - проблема в этом:[root@localhost]# nm libhello.so.0
000017d0 A __bss_start
00000520 t call_gmon_start
000017d0 b completed.5604
000016b4 d __CTOR_END__
000016b0 d __CTOR_LIST__
w __cxa_finalize@@GLIBC_2.1.3
00000600 t __do_global_ctors_aux
00000550 t __do_global_dtors_aux
000017c8 d __dso_handle
000016bc d __DTOR_END__
000016b8 d __DTOR_LIST__
000016c4 A _DYNAMIC
000017d0 A _edata
000017d4 A _end
00000644 T _fini
000005b0 t frame_dummy
000006ac r __FRAME_END__
000017b8 A _GLOBAL_OFFSET_TABLE_
w __gmon_start__
U __gxx_personality_v0@@CXXABI_1.3
000005e5 t __i686.get_pc_thunk.bx
000004e4 T _init
000016c0 d __JCR_END__
000016c0 d __JCR_LIST__
w _Jv_RegisterClasses
000017cc d p.5602
U printf@@GLIBC_2.0
000005ec T _Z5hellov << вот это нужно было указать в dlsym//---
#include<dlfcn.h>
#include<stdio.h>typedef void (*simple_demo_function)(void);
int main(void)
{
const char *error;
void *module;
simple_demo_function demo_function;
module = dlopen("libhello.so", RTLD_LAZY);
if (!module)
{
fprintf(stderr, "Couldn't open libhello.so: %s\n", error);
}dlerror();
demo_function = (simple_demo_function) dlsym(module, "_Z5hellov");
if ((error = dlerror()))
{
fprintf(stderr, "Couldn't find hello: %s\n", error);
}
(*demo_function)();
dlclose(module);
return 0;
}[root@localhost]# ./demo
Hello world!:)
>А новая ошибка - это уже собсем другая проблема: C++ name mangling
>- поскольку вы компилировали libhello как C++, реальное (видимое линкером) имя
>функции hello() на самом деле не "hello" а нечто иное, построенное
>компилятором g++ по неким правилам по которым в имени закодированы тип
>возвращяемого значения и типы параметров (google "g++ name mangling").
>
>Попробуйте с помощью команды "nm" посмотреть какие имена содержит построенная библиотека libhello.so
>- вот такое имя и надо указать в dlsym(module, "mangled_name_of_hello").Может написать extern "C", тогда имя функции должно быть hello