LINUX.ORG.RU

С++ dynamic_cast в .so не работает


0

0

Столкнулся с проблемой некорректной работы dynamic_cast в G++ в лінуксе в шаблонных классах. Ситуация такая: написана библиотека, для этой библиотеки через SWIG написан .so модуль для Питона. Если вызывать методы моей либы из модуля, то динамик каст там не работает, если библиотеку прилинковать к своей программе, т.е. по-нормальному (не через dlopen и т.п.), то работает. Технические детали:

1) есть динамическая библиотека (shared object) OpenSceneGraph, в которой определён сложный шаблонный класс Vec3Array, один из отцов которого в иерархии является класс Array.

2) в этой библиотеке создаётся экземпляр данного класса и возвращается указатель типа Array

3) в моей динамической библиотеке (MyLib) получается указатель на данный экземпляр от библиотеки его создавшей (OpenSceneGraph) и через dynamic_cast приводится в указатель типа Vec3Array.

4) если я линкую свою библиотеку в свою программу, то dynamic_cast возращает правильный указатель, т.е. dynamic_cast<Vec3Array*>(getArray()) работает

5) ПРОБЛЕМА: есть третья библиотека (SwigWrappedModule) которая динамически линукуется с моей библиотекой (MyLib), но первая не линкуется с программой динамически по-умолчанию, а загружается через dlopen, и вызывает функции последней. Так вот, в этом случае (когда мои функции вызываются из третьей библиотеки) dynamic_cast возвращает ноль, хотя на самом деле указатель на тип правильный и там реально находится объект типа Vec3Array (проверяется средствами OpenSceneGraph после dynamic_cast на базовый НЕшаблонный класс Object)

Итак 1) MyProgram->MyLib->OSG -- works 2) someProgram... someLibrary->MyLib->OSG -- no dynamic cast

Данную проблему гуглом нашёл, оказывается проблема в шаблонах, копии которого раскиданы по разным библиотекам из-за чего получается, что их typeinfo несовместимы.

Кто с такими делами сталкивался, как решал?


> Данную проблему гуглом нашёл, оказывается проблема в шаблонах, копии которого раскиданы по разным библиотекам из-за чего получается, что их typeinfo несовместимы.

(интересуюсь) ссылку?

www_linux_org_ru ★★★★★
()

dll hell в действии

вообще на будущее если хотите избежать таких проблем используйте для библиотек экспортирумые C функции, а в С++ используйте обертки над ними

acefsm
()
Ответ на: комментарий от www_linux_org_ru

Вот похожие ситуации:

http://www.cpptalk.net/dynamiccast-and-dynamic-libraries-vt12388.html

http://osdir.com/ml/gcc.help/2003-07/msg00225.html

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

http://gcc.gnu.org/faq.html#dso

Более того, эта же проблема всплывёт при обработке исключений -- они не будут ловиться :( Остаётся проверить, не передаётся ли флаг -Bsymbolic.

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

Кажется у меня на работе во внутренней wiki есть годная статья для разработчиков на эту тему (про so/dll, vtable и исключения) - применительно к gcc и vc. В понедельник отпишусь более конкретно, если ты решения не найдешь.

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

> есть годная статья для разработчиков на эту тему (про so/dll, vtable и исключения)

будьте так любезны, предоставте тут выдержки.

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

> будьте так любезны, предоставте тут выдержки.

К сожалению, применительно к твоей проблеме я из этой статьи ничего интересного не почерпнул. Помимо прочего там рассказывается только о механизмах динамической линковки Windows/vc++ и Linux/g++, а также проблемах при нарушении принципа ODR (One Definition Rule) и как их избежать. Судя по тому, что в твоей тестовой программе либа используется нормально - это другой случай.

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