Как связать с двумя общими библиотеками со многими конфликтующими функциями
В настоящее время я работаю с двумя сторонними общими библиотеками (A.so и B.so) в Linux. проблема заключается в том, что оба этих компонента статически связаны с другой библиотекой, в результате чего около 400 функций из A.so и B.so имеют одинаковые имена. Когда я компилирую и связываю с -lA -lB или -lB -lA, в зависимости от порядка функции выбираются из A или B отдельно в результате взаимного расположения функций, которое вызвало проблему, и код не может быть запущен. Мне интересно, есть ли способ связать имена функций с их библиотеками, чтобы обе библиотеки могли быть связаны и использованы? потому что эти перекрывающиеся имена функций вызываются внутри A и B, поэтому я не могу использовать такие вещи, как objcopy и т. д. Поможет ли dlopen?
1 ответ
Мне интересно, есть ли способ связать имена функций с их библиотеками, чтобы обе библиотеки могли быть связаны и использованы?
Когда две библиотеки были связаны, они должны были контролировать символы, которые они экспортируют, и должны были скрыть "другую" библиотеку, но они не...
будет помогать?
Да, если вы dlopen("A.so", RTLD_LOCAL);
а также dlopen("B.so", RTLD_LOCAL);
тогда ни одна библиотека не будет добавлена в глобальную область, и они не будут "видеть" друг друга.
Вам придется явно искать нужные символы из A.so
а также B.so
, но это лучшее, что ты мог сделать.
Обновить:
Есть ли быстрый способ ссылки на статическую библиотеку без экспорта символов из этой "другой" библиотеки при сборке A.so
Это лучше всего сделать с помощью -fvisibility=hidden
флаг и __attribute__((visibility("default")))
на символы, которые должны быть экспортированы. Пример:
#define EXPORTED __attribute__((visibility("default")))
struct Foo {
void EXPORTED ExportedFunction();
void EXPORTED AnotherExportedFunction();
void InternalFunction();
};
void Foo::ExportedFunction() { }
void Foo::AnotherExportedFunction() { }
void Foo::InternalFunction() { }
gcc -shared -fPIC -o foo.so foo.cc
nm -CD foo.so | grep Foo::
00000000000005fc T Foo::ExportedFunction()
0000000000000610 T Foo::InternalFunction()
0000000000000606 T Foo::AnotherExportedFunction()
Без явного контроля экспорта все экспортируется (включая InternalFunction
мы не хотим).
gcc -shared -fPIC -o foo.so foo.cc -fvisibility=hidden
nm -CD foo.so | grep Foo::
00000000000005bc T Foo::ExportedFunction()
00000000000005c6 T Foo::AnotherExportedFunction()
Вуаля: только то, что мы явно хотели экспортировать.