Форум русскоязычного сообщества Ubuntu


Следите за новостями русскоязычного сообщества Ubuntu в Twitter-ленте @ubuntu_ru_loco

Автор Тема: char* в параметрах динамических библиотек .so через g++  (Прочитано 1605 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн BestSacred

  • Автор темы
  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Люди подскажите пожалуйста. Только начал осваивать С++ под Linux на Ubuntu 10,04 и столкнулся с такой проблемой при разработке динамической библиотеки so.
Беру примеры которых полно в инете. собираю вызывающую программу и собираю библиотеку. Все работает.
Как только добавляю параметр типа char * (с интами и флоатами все нормально) получается фигня (библиотечная функция вызывается но при первом обращении к строковому параметру выскакивает ошибка "Ошибка сегментирования", и портится следующий за этой строкй интовый параметр - показывает не то что передали, все интовые параметры которые в параметрах до char* ведут себя отлично)
при чем если собирать библиотеку через gcc то все нормально. но как только этот файл собираешь через g++  получается вот такая фигня.
Скажите как передавать строки правильно для g++.

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
абсолютно ни чем не отличается
разберись с С++
возможно ты где-то передаёшь const char * в char* и пытаешься изменить его. поэтому и получаешь SEGFAULT
(Нажмите, чтобы показать/скрыть)

Оффлайн BestSacred

  • Автор темы
  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Передаю я и const char*  , и через char *, а вот изменить я его не пытаюсь , вываливается при попытке просто вывести строку на консоль
printf("\n**%s**\n",asd);

И если я напутал с char, то почему когда я компилю gcc все нормально, а когда не изменяя программы , этот же файл компилю g++, получается вот такая фигня.

lib.c
#include <stdio.h>
double power2(double x, char *asd)
{
printf("\n**%s**\n",asd);
return x*x;
}
double power3(double x)
{
return x*x*x;
}


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

int main(int argc, char* argv[])
{
void *ext_library;
double value = 0;
double (*powerfunc)(double x, char *qqq);

printf("Hello! Start");
ext_library = dlopen("./libpowers.so",RTLD_LAZY);
if(!ext_library)
{
fprintf(stderr,"dlopen() error: %s\n",dlerror());
return 1;
}
powerfunc = dlsym(ext_library,"power2");
value = 3.0;

printf("%s(%f) = %f\n",argv[1],value,(*powerfunc)(value, "zzz"));

dlclose(ext_library);
}

теперь  компилю:
g++ main.c -ldl

g++ -fPIC -c lib.c
g++ -shared lib.o -o libpowers.so

при выполнении ошибка сегментирования. если теперь не изменяя файл бибилиотеки перекомпилить
gсс -fPIC -c lib.c
gсс -shared lib.o -o libpowers.so
то все работает нормально.

Оффлайн ierofant

  • Любитель
  • *
  • Сообщений: 52
    • Просмотр профиля
Ты определись на каком ты языке пишешь, на C или на C++. Строка в стиле C++ называется std::string. А ты используешь строки в стиле С, и вообще очень много в твоём коде С-style, printf тот же.

Оффлайн wl

  • Старожил
  • *
  • Сообщений: 1393
    • Просмотр профиля
Дело в name mangling.
Плюсовый компилятор искажает имена функций.
В созданной библиотеке нет символа power2, и dlsym возвращает хрензнаетчо.
Если добавить вызов dlerror после dlsym, это сразу станет видно.
Надо в исходниках библиотеки каждую функцию объявлять extern "C"
Ссылка по теме: http://www.faqs.org/docs/Linux-mini/C++-dlopen.html#thesolution

$ nm -A libpowers.so
libpowers.so:00002010 d DW.ref.__gxx_personality_v0
libpowers.so:00001f00 a _DYNAMIC
libpowers.so:00001ff4 a _GLOBAL_OFFSET_TABLE_
libpowers.so:         w _Jv_RegisterClasses
libpowers.so:0000055c T _Z6power2dPc
libpowers.so:0000059b T _Z6power3d
libpowers.so:00001ef0 d __CTOR_END__
libpowers.so:00001eec d __CTOR_LIST__
libpowers.so:00001ef8 d __DTOR_END__
libpowers.so:00001ef4 d __DTOR_LIST__
libpowers.so:00000690 r __FRAME_END__
libpowers.so:00001efc d __JCR_END__
libpowers.so:00001efc d __JCR_LIST__
libpowers.so:00002014 A __bss_start
libpowers.so:         w __cxa_finalize@@GLIBC_2.1.3
libpowers.so:000005c0 t __do_global_ctors_aux
libpowers.so:000004a0 t __do_global_dtors_aux
libpowers.so:0000200c d __dso_handle
libpowers.so:         w __gmon_start__
libpowers.so:         U __gxx_personality_v0@@CXXABI_1.3
libpowers.so:00000557 t __i686.get_pc_thunk.bx
libpowers.so:00002014 A _edata
libpowers.so:0000201c A _end
libpowers.so:000005f8 T _fini
libpowers.so:00000428 T _init
libpowers.so:00002014 b completed.7021
libpowers.so:00002018 b dtor_idx.7023
libpowers.so:00000520 t frame_dummy
libpowers.so:         U printf@@GLIBC_2.0

Обратите внимание, там вместо power2 _Z6power2dPc
Если заменить в dlsym "power2" на "_Z6power2dPc", все работает.

« Последнее редактирование: 26 Октября 2010, 11:49:03 от wl »
На свете феньки есть такие, брат Горацио, которых лохи просто не секут. (Шекспир, "Гамлет", вольный перевод)

Оффлайн BestSacred

  • Автор темы
  • Новичок
  • *
  • Сообщений: 3
    • Просмотр профиля
Всем спасибо. Я разобрался. Действительно пропустил extern "C".

Оффлайн Yurror

  • Старожил
  • *
  • Сообщений: 1966
    • Просмотр профиля
да... действительно. просто точнее надо вопросы формулировать. надо было начинать с твоего второго поста, а первый выкинуть нафиг =)
Почему все хотят чтобы форумчане потренировались в прикладной телепатии?

 

Страница сгенерирована за 0.021 секунд. Запросов: 21.