URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 5893
[ Назад ]

Исходное сообщение
"Проблема приведения типа!"

Отправлено gcc , 10-Ноя-06 01:08 
Возникла проблема при компиляции программы, связанная с проверкой типов данных.

Код:

#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 (*)()'


Долго парился, искал по всему инету - ничего не нашел.

Помогите, плиз, если не составит труда.
Может какой-нибудь флажок поставить нужно, чтобы отключить жесткую проверку типов или еще чего-нибудь :)

Заранее респект!


Содержание

Сообщения в этом обсуждении
"Проблема приведения типа!"
Отправлено elvenic , 10-Ноя-06 01:30 
>Возникла проблема при компиляции программы, связанная с проверкой типов данных.
>
>Код:
>
>#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, может поможет.

    


"Проблема приведения типа!"
Отправлено gcc , 11-Ноя-06 01:09 
>>Возникла проблема при компиляции программы, связанная с проверкой типов данных.
>>
>>Код:
>>
>>#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 до последней версии ... не помогло.
Неужели ни у кого нет опыта по этому вопросу... =(

Готовлю веревку и мыло :(


"Проблема приведения типа!"
Отправлено elvenic , 11-Ноя-06 05:35 
>
>К сожалению, это не помогло(ошибок компиляции нет, но появилась ошибка при выполнении
>программы)... хотя была надежда =(
>Выдает ошибку:
>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").


"Проблема приведения типа!"
Отправлено gcc , 11-Ноя-06 10:13 
>>
>>К сожалению, это не помогло(ошибок компиляции нет, но появилась ошибка при выполнении
>>программы)... хотя была надежда =(
>>Выдает ошибку:
>>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!

:)


"Проблема приведения типа!"
Отправлено sandy , 12-Ноя-06 13:55 
>А новая ошибка - это уже собсем другая проблема: C++ name mangling
>- поскольку вы компилировали libhello как C++, реальное (видимое линкером) имя
>функции hello() на самом деле не "hello" а нечто иное, построенное
>компилятором g++ по неким правилам по которым в имени закодированы тип
>возвращяемого значения и типы параметров (google "g++ name mangling").
>
>Попробуйте с помощью команды "nm" посмотреть какие имена содержит построенная библиотека libhello.so
>- вот такое имя и надо указать в dlsym(module, "mangled_name_of_hello").

Может написать extern "C", тогда имя функции должно быть hello