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

Исходное сообщение
"Линковка в периоде исполнения (dlsym)"

Отправлено Bave , 04-Янв-08 14:54 
Вообщем написал библиотеку, откомпилировал её так:
g++ -fPIC -c igate.cpp -o igate.o
g++ -shared -o libigate.so igate.o
В результате получил библиотеку:
libigate.so
Теперь пытаюсь её использовать:
1. сначало подгружаю её используя dlopen(libname, flags). Библиотека подгружается без
проблем никаких ошибок.
2. Но вот когда пытаю получить указатель функции, получаю ошибки, например:
после выполнения dlsym(hGate, "httplookup") - dlerror возвращает: "./libigate.so: undefined symbol httplookup". И такая проблема с любой функцией.
----------------------------------------------
Попробовал даже для проверки простенькую тестовую библиотеку написать:
типа:
1. testdl.cpp:
int tester(int i) { return i; }
2. g++ -fPIC -c testdl.cpp -o testdl.o
   g++ -shared -o libtestdl.so testdl.o
3. уже в программе:
hLib = dlopen("./libtestdl.so", RTLD_LAZY);
lpfnTester = dlsym(hLib, "tester");
И опять та же фигня: ./libtestdl.so: undefined symbol tester
--------------------------------------------------
Как же тогда имена функций указывать надо?
Или может я библиотку не правильно собираю...



Содержание

Сообщения в этом обсуждении
"Линковка в периоде исполнения (dlsym)"
Отправлено Volody , 04-Янв-08 15:24 
объяви функцию tester как
extern "C" int tester(int i) { return i; }

"Линковка в периоде исполнения (dlsym)"
Отправлено Bave , 04-Янв-08 20:44 
>объяви функцию tester как
>extern "C" int tester(int i) { return i; }

Точно, заработало :)
Есть ещё вопрос - А как быть с функциями, заключёнными в пространства имён. Или придётся отказаться от использования пространств имён?


"Линковка в периоде исполнения (dlsym)"
Отправлено Volody , 05-Янв-08 10:03 
многое определяеться практическим методом - попробуй. В моей практике не было необходимости использовать пространства имен, но теоретически проблем не должно быть.

"Линковка в периоде исполнения (dlsym)"
Отправлено Alexander S. Salieff , 05-Янв-08 20:34 
>>объяви функцию tester как
>>extern "C" int tester(int i) { return i; }
>
>Точно, заработало :)
>Есть ещё вопрос - А как быть с функциями, заключёнными в пространства
>имён. Или придётся отказаться от использования пространств имён?

В dlsym имена функций совпадают с прототипными только в стабильном C-ABI (от этого при линковке с g++ ничего и не работает, пока extern "C" не скажешь). Если вы хотите использовать C++-ABI, вам придется вручную заниматься name-mangling'ом, будете вместо basic_ios::char_traits::eof вычислять конструкции вида _ZNKSt9basic_iosIcSt11char_traitsIcEE3eofEv@@GLIBCXX_3.4. Плюс ко всему команда gcc периодически ломает C++-ABI от версии к версии. Вследствие этих причин обычно используют C-ABI.


"Линковка в периоде исполнения (dlsym)"
Отправлено Michelnok , 06-Янв-08 17:51 
>придется вручную заниматься name-mangling'ом

Кстати, а нет ли какой-нибудь библиотеки?
Иначе говоря, не торчит ли наружу то что использует gcc для формирования имен?


"Линковка в периоде исполнения (dlsym)"
Отправлено Аноним , 06-Янв-08 20:16 
>а нет ли какой-нибудь библиотеки?

Наверняка нет. ПОтому что как сказали выше, схема именования имеет свойство менятся, обычно при большой смене версии.

В любом случае, если делаешь плагин, число экспортируемых функций должно быть маленькое, и коллизии имён не произойдёт (namespace не нужен). Напиши "С" интерфейсные обёртки для всех экспортируемых методов.

А если не плагин - то пусть компиляторы, линковщики и загрузчики парятся с этими искажёнными именами :)


"Линковка в периоде исполнения (dlsym)"
Отправлено Bave , 06-Янв-08 23:32 
Решил не создавать себе лишних проблем и просто обернул всё в extern "C",
пространства имён убрал, а к именам функций просто префиксы добавил ig..., т.е. igFuncname.
Пока всё без глюков работает :)



"Линковка в периоде исполнения (dlsym)"
Отправлено Аноним , 07-Янв-08 11:36 
>Решил не создавать себе лишних проблем и просто обернул всё в extern
>"C"

Надо ли всё?

Ты не сможешь написать так:
int abs (inf)
double abs (double)

Потому что обе эти функции будут иметь одно имя. В лучшем случае линкер даст ошибку, в худшем - он их перепутает.


"Линковка в периоде исполнения (dlsym)"
Отправлено Alexander S. Salieff , 08-Янв-08 03:44 
>[оверквотинг удален]
>>"C"
>
>Надо ли всё?
>
>Ты не сможешь написать так:
>int abs (inf)
>double abs (double)
>
>Потому что обе эти функции будут иметь одно имя. В лучшем случае
>линкер даст ошибку, в худшем - он их перепутает.

Линкер ошибку не даст, и ничего не перепутает. Сишный компилятор не скомпиляет, т.к. стандарт запрещает перегрузку функций, плюсовый скомпиляет, но с замэнгленными именами вроде _Z3absd...


"Линковка в периоде исполнения (dlsym)"
Отправлено Аноним , 08-Янв-08 22:11 
>Линкер ошибку не даст, и ничего не перепутает.

Блажен кто верует ;)

> Сишный компилятор не скомпиляет, т.к. стандарт запрещает перегрузку функций

Ещё бы он знал что есть функция с таким же именем. Если в 1 файле, то он узнает. А если в разных, ещё как скомпилирует :)

> плюсовый скомпиляет, но с замэнгленными именами

C extern "C" -то?