LINUX.ORG.RU

Линковка библиотеки


0

0

Здравствуйте! Такая проблема, допустим у меня есть какая-то shared-object (SO), в которой есть глобальная процедура

void extern "C" __attribute__ ((visibility("default"))) foo(void) { printf ("I am foo of first SO!\n"); }

SO компилится с -fvisibility=hidden (компилер = g++), то есть в итоге мы будем видеть этот фу...

Вооот,... теперь мы создаём вторую SO, в которую добавляем еналогичную процедуру (более того - одноимённую)

void extern "C" __attribute__ ((visibility("default"))) foo(void) { printf ("I am foo of second SO!\n"); }

И главное - ЛИНКУЕМ ВТОРУЮ БИБЛИОТЕКУ С ПЕРВОЙ!!!

Внимание вопрос: Какие флаги мне нужно передавать в линкуовку либы 2, чтобы в неё добавлялось тело функции именно этой библиотеки (то есть foo 2-ой либы)

А то получается, например:

typedef void (*FOO)();

FOO foo1; FOO foo2;

void *handle1 = dlopen("lib1.so", RTLD_GLOBAL | RTLD_LAZY | RTLD_NODELETE);

void *handle2 = dlopen("lib2.so", RTLD_GLOBAL | RTLD_LAZY | RTLD_NODELETE);

foo1 = (FOO)dlsym(handle1,"foo"); foo2 = (FOO)dlsym(handle2,"foo");

foo1(); foo2();

------------RESULT---------

I am foo of first SO! I am foo of first SO!

вместо

I am foo of first SO! I am foo of second SO!

То есть глобалы не затираются, а берутся из старой либы, которую я прилинковываю к текущей. В Винде всё это разруливается каким-то образом, а вот в линуксе возникают проблемы. Кто нибудь знает какие это заветные флаги позволяющие затирание телами второй либы тел первой?!

Спасибо.

>void extern "C" __attribute__ ((visibility("default"))) foo(void) { printf ("I am foo of first SO!\n"); }

Предположительно здесь перетирается ключ компилера -fvisibility=hidden

cvv ★★★★★
()
Ответ на: комментарий от no_NaMe

Более того - я компилил вообще без visibility - всё равно такая проблема остаётся! (так же из определений класса были убраны visibility (осталось только extern "C"))...

no_NaMe
() автор топика
Ответ на: комментарий от no_NaMe

Мож ты таки прочтёш доку к компилеру и линкеру?!!!

а вообще кажись твоя задача нерешаема: скрытые символы dlopen видеть не должна...

cvv ★★★★★
()
Ответ на: комментарий от cvv

В том то и фишка, что attribute ("default") делает скрытые символы видимыми!!!

Доку к компилеру и линкеру я читал - иначе зачем я здесь?! Если бы я там нашёл - то не стал бы обращаться на форум!!!

Задачу я уже решил, правда не понял почему это происходит. (Перестал использовать boost::python во втором модуле - вроде заработало).

no_NaMe
() автор топика
Ответ на: комментарий от no_NaMe

>В том то и фишка, что attribute ("default") делает скрытые символы видимыми!!!

В правильном направлении мыслишшш

а теперь подумай что будет если у твоей программы два видимых символа с одинаковыми именами и ты поймёш откудова ноги растут...

>Доку к компилеру и линкеру я читал - иначе зачем я здесь?! Если бы я там нашёл - то не стал бы обращаться на форум!!!

Ну так бы и написал: прочесть-прочёл но ничего не понял. Естественно там ответа нету. просто ты бы понял чем страдаеш...

cvv ★★★★★
()
Ответ на: комментарий от cvv

>void *handle1 = dlopen("lib1.so", RTLD_GLOBAL | RTLD_LAZY | RTLD_NODELETE);

крышу в *частично* срывает RTLD_LAZY. ну и естественно непонимание того чем ты занимаешся...

cvv ★★★★★
()
Ответ на: комментарий от cvv

Ок! Как работает: На питоне написан гуй, а ядро - на C++, Так же на boost::python написан wrapper C++ -> Python,.. вот когда я начинаю создавать модули на boost::python начинает просходить такая фигня...

Ядро будет загружать модули один за другим и для их регистрации мне нужна глобальная проэкспортированная в каждую либу процедура. Допустим это foo(). Вот так это всё работает.

no_NaMe
() автор топика
Ответ на: комментарий от no_NaMe

:-)

Эт я уже понял. Я хотел услышать от того анонимуса как работают weak символы ато я с ними дела пока не имел

ты кстати можеш дать одной ф-и два имени - одно для линковки к другим модулям а второе для вызова из ядра. Возможно это будет одним из самых красивых решений

cvv ★★★★★
()
Ответ на: комментарий от no_NaMe

>Как пометить, прости (я не в теме)

Например, описав функцию с __attribute__ ((weak))

anonymous
()
Ответ на: комментарий от cvv

> ты кстати можеш дать одной ф-и два имени - одно для линковки к другим модулям а второе для вызова из ядра

А как это можно сделать, не подскажешь?

no_NaMe
() автор топика
Ответ на: комментарий от no_NaMe

> А как это можно сделать, не подскажешь?

Например, с помощью атрибута alias.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.