LINUX.ORG.RU

При линковке изолировать от остального проекта символы из библиотеки

 , , , ,


0

3

Есть SDK для IP камеры от китайцев в виде библиотеки (на выбор .a и .so) и заголовочного файла, исходников нет. К этой библиотеке статически слинкована другая библиотека live555. Китайцы через неё тянут поток по rtsp. Всё прекрасно работает.

Но мне в проекте тоже понадобилось использовать live555, но новой версии и собранной с нужными ключами. При попытке собрать это в рамках одного приложения происходит облом. Я пытался по-разному. Либо конфликты при линковке (ругается на __cxx что-то там и таблицы виртуальных функций) либо китайский live555 берёт верх и мой код начинает работать со старой китайской версией. Пробовал использовать -fvisibility=hidden, методы классов перестали торчать, но вот служебная c++ требуха всё ещё торчит.

Вопрос. Как-нибудь можно их изолировать друг от друга в рамках одного адресного пространства? В идеале, чтобы из китайца торчали только нужные мне функции. Хоть внутри там c++, но API у библиотеки сишный. Или это невозможно из-за одинаковых имён символов?

★★★

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

pon4ik ★★★★★ ()

Похожую проблему я решил методом грубого хакинга, а именно переименовал старые либы и отредактировал либу, которая требовала старые либы, просто поменяв в бинарном файле название требуемой библиотеки. Работает :)

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

Нифига не получилось. Библиотека вызывает коллбек, я в нём пытаюсь что-то сделать и программа падает. Этот же код работает нормально если линковаться по-традиционному.
Загружаю библиотеку так:

int flags = RTLD_NOW;
void *pthread = dlmopen(LM_ID_NEWLM, "libpthread.so", flags);

Lmid_t ns;
if (dlinfo(pthread, RTLD_DI_LMID, &ns) == 0)
    _libHandle = dlmopen(ns, LIBNAME, flags);

Стек вызовов в момент падения:

1  __gettext_extract_plural                                                                                                                                                                                                                        0x7fffeef96cbf 
2  _nl_load_domain                                                                                                                                                                                                                                 0x7fffeef93fd2 
3  _nl_find_domain                                                                                                                                                                                                                                 0x7fffeef93b26 
4  __dcigettext                                                                                                                                                                                                                                    0x7fffeef931f0 
5  ??                                                                                                                                                                                                                                              0x7fff9e024a57 
6  g_type_class_ref                                                                                                                                                                                                                                0x7ffff1767e72 
7  g_object_new_valist                                                                                                                                                                                                                             0x7ffff1785588 
8  g_object_new                                                                                                                                                                                                                                    0x7ffff1785c8a 
9  gst_element_factory_create                                                                                                                                                                                                                      0x7ffff195bc57 
10 gst_element_factory_make                                                                                                                                                                                                                        0x7ffff195c6cd                                                                                                                                                                                                                                                      

Хз из-за чего такое происходит.

ox55ff ★★★ ()

Короче, какая-то фигня с многопоточностью, видимо из-за двух копий pthread. Если я дёргаю gstreamer из потока, который создаёт изолированная библиотека, то всё валится. Но если я перекину данные в другой поток, то всё работает. Так что способ с dlmopen работает, но не из коробки. Могут быть косяки.

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

Короче, какая-то фигня с многопоточностью, видимо из-за двух копий pthread.

Сперва надо узнать, что там статически вкомпилено у китайцев. Как пример, если вкопилен glib (не glibc) с его (многопоточными) счетчиками ссылок со сборкой мусора g_object’ов, то тебе придется очень аккуратно работать c g_object’ами, и желательно не передавать между своей частью и китайской, не известно где стриггерит сборку мусора и какая версия сборки отработает, включая (многопоточную) работу со счетчикам ссылок. А там у тебя еще с++ лезет…

Правильнее и проще всего изолировать их в разных процессах.

anonymous ()