Вообщем написал библиотеку, откомпилировал её так:
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
--------------------------------------------------
Как же тогда имена функций указывать надо?
Или может я библиотку не правильно собираю...
объяви функцию tester как
extern "C" int tester(int i) { return i; }
>объяви функцию tester как
>extern "C" int tester(int i) { return i; }Точно, заработало :)
Есть ещё вопрос - А как быть с функциями, заключёнными в пространства имён. Или придётся отказаться от использования пространств имён?
многое определяеться практическим методом - попробуй. В моей практике не было необходимости использовать пространства имен, но теоретически проблем не должно быть.
>>объяви функцию 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.
>придется вручную заниматься name-mangling'омКстати, а нет ли какой-нибудь библиотеки?
Иначе говоря, не торчит ли наружу то что использует gcc для формирования имен?
>а нет ли какой-нибудь библиотеки?Наверняка нет. ПОтому что как сказали выше, схема именования имеет свойство менятся, обычно при большой смене версии.
В любом случае, если делаешь плагин, число экспортируемых функций должно быть маленькое, и коллизии имён не произойдёт (namespace не нужен). Напиши "С" интерфейсные обёртки для всех экспортируемых методов.
А если не плагин - то пусть компиляторы, линковщики и загрузчики парятся с этими искажёнными именами :)
Решил не создавать себе лишних проблем и просто обернул всё в extern "C",
пространства имён убрал, а к именам функций просто префиксы добавил ig..., т.е. igFuncname.
Пока всё без глюков работает :)
>Решил не создавать себе лишних проблем и просто обернул всё в extern
>"C"Надо ли всё?
Ты не сможешь написать так:
int abs (inf)
double abs (double)Потому что обе эти функции будут иметь одно имя. В лучшем случае линкер даст ошибку, в худшем - он их перепутает.
>[оверквотинг удален]
>>"C"
>
>Надо ли всё?
>
>Ты не сможешь написать так:
>int abs (inf)
>double abs (double)
>
>Потому что обе эти функции будут иметь одно имя. В лучшем случае
>линкер даст ошибку, в худшем - он их перепутает.Линкер ошибку не даст, и ничего не перепутает. Сишный компилятор не скомпиляет, т.к. стандарт запрещает перегрузку функций, плюсовый скомпиляет, но с замэнгленными именами вроде _Z3absd...
>Линкер ошибку не даст, и ничего не перепутает.Блажен кто верует ;)
> Сишный компилятор не скомпиляет, т.к. стандарт запрещает перегрузку функций
Ещё бы он знал что есть функция с таким же именем. Если в 1 файле, то он узнает. А если в разных, ещё как скомпилирует :)
> плюсовый скомпиляет, но с замэнгленными именами
C extern "C" -то?