Как создать приложение, которое требует как libstdC++. So.5, так и libstdC++. So.6?
Я хочу предварить это важным замечанием, что я не программист на C/C++ и очень мало знаю о том, как работает связывание библиотек в C.
Наш код использует libstdC++. So.6 (думаю, gcc 3.4). У нас есть сторонние предварительно скомпилированные (с закрытым исходным кодом) библиотеки, которые используют libstdC++. So.5 (gcc 2.something или 3.2, я думаю). Это на Linux. У нас есть версия.a и.so сторонней библиотеки lib.
Можно ли построить наше приложение с помощью сторонних библиотек? Как? Можно ли собрать / запустить наше приложение без установки libstdC++. So.5 наших машин, как?
Если я забыл некоторую важную информацию, пожалуйста, дайте мне знать - я едва знаю, что относится к этому материалу. Я понимаю, что полный ответ, вероятно, будет невозможен; Я действительно ищу направление и руководство. Статическое связывание этого, динамическое то, перестройте это, предварительно соберите то-то и то-то, переключитесь на версию x, или символическую ссылку на тест и так далее.
Обновить:
Мы пытались использовать dlopen
с RTLD_LOCAL
изолировать стороннюю библиотеку от остальной части нашего приложения. Похоже, это в основном сработало, однако по неизвестным причинам у нас остались большие утечки памяти. Мы подозреваем, что, когда мы звоним dlopen
, сторонняя библиотека тянет в символы как malloc
из уже загруженного.so.6, и вещи запутываются.
Для хихиканья мы попытались поместить стороннюю библиотеку в LD_PRELOAD
, а затем запустил наше приложение, и утечки памяти, кажется, полностью исчезают.
4 ответа
Вы можете попытаться создать библиотеку-оболочку вокруг сторонней библиотеки: используйте статическую версию этой библиотеки + свяжите ее со стандартной статической библиотекой (-static-libgcc - убедитесь, что вы выбрали правильную версию через -L). Важно правильно закрыть библиотеку-оболочку, т. Е. Нужно экспортировать только символы из исходной сторонней библиотеки, а все остальное следует скрыть. Таким образом, ваша библиотека-обертка будет отображать все необходимые символы для вашего приложения и инкапсулировать стандартные вещи внутри. Обратите внимание, что не гарантируется работа, особенно если некоторые операции с памятью распределяются между вашим кодом и кодом третьей стороны (например, вы выделяете память в своем коде и освобождаете в третьей стороне)... в таком случае единственным вариантом может быть сохранение этой третьей партия lib в другом пространстве процесса.
Я не думаю, что упомянутая выше динамическая опция сработает, потому что вы получите точно такую же проблему - чуть позже.
В общем случае лучше не смешивать двоичные файлы с разными временами выполнения в одном и том же пространстве процесса. Это почти всегда рецепт катастрофы.
Спросите у своего поставщика более новую версию библиотеки, которая использует кое-что не ужасно устаревшее. В противном случае вы можете увидеть, работает ли ваше новое приложение со старой версией библиотеки, и при необходимости перенести ее обратно. Попытка получить две разные версии одной и той же библиотеки требует боли, и я не думаю, что вы найдете приемлемое решение.
Хотя легко связать и libstdC++. So.6, и libstdC++. So.5 одновременно с вашим приложением, его поведение в значительной степени будет неопределенным, поскольку символы берутся из любой библиотеки в основном случайно.
Лучший способ добиться успеха IMO - это создать собственное приложение на основе сторонней библиотеки на старой системе (которая использует совместимый gcc, например, gcc 3.3) и позволить ему обмениваться данными с вашим основным приложением через IPC (например, shared). объем памяти). Сюда нет
Если вы не хотите хранить libstdC++. So.5 в вашей целевой системе, то это просто: используйте флаг gcc -static, чтобы связать libstdC++. A с вашим приложением-оболочкой.
Хотя один из приведенных подходов может сработать, я думаю, что безопаснее сказать, что вы не можете сделать это напрямую надежным способом. Если вы напишите обертку с использованием полностью API на основе C (только C-совместимые структуры, память, управляемая malloc/free и т. Д.), То вы можете использовать решение pobedim. Однако, если вам нужно обмениваться структурами C++, это небезопасно, поскольку, даже если вы могли бы создать ссылку, реализации разных стандартных библиотек могли бы использоваться для одних и тех же объектов. Кроме того, ABI C++ может быть несовместим с основами кода на основе.5 и.6 (я точно не помню, как несколько лет назад произошло серьезное изменение ABI в Gnu C++, связанное со звуковыми именами стандартной библиотеки).
Я думаю, что самый безопасный подход к решению этой проблемы - это использовать многопроцессорный подход с каким-то IPC между вашим приложением и процессом ресурсного / вычислительного сервера, построенным на рассматриваемой библиотеке. Вы можете использовать CORBA, D-Bus, Sun RPC или какой-то специальный протокол по каналам или сокетам для выполнения этой работы. Я сделал это, когда пытался использовать 32-битный код с закрытым исходным кодом в 64-битных приложениях, и он работает достаточно хорошо. Вы увидите снижение производительности, но вы также полностью обойдете проблемы, связанные с попыткой смешать среды выполнения C++ в одном процессе.