проблемы динамического связывания с использованием c ++ - PullRequest
1 голос
/ 01 октября 2009

Запуск всего этого приведет к следующей ошибке:

Cannot open library "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: _ZTI10BaseFilter

Поскольку код довольно маленький и понятный, вы сможете понять его сразу. Кто-нибудь знает, что не так?

Должен ли я сделать, а объявить create () как extern "C" void * create (void); и затем привести указатель void вместо прямой попытки связать символы c ++?

Следующий шаг

после использования -Wl,-export-dynamic, он говорит мне:

Cannot load library symbols "./libexamplefilter.so" ./libexamplefilter.so: undefined symbol: create

Э-э, мне нужно дать искаженное имя c ++ вместо "dlsym (handle," create ")". Наверное. Есть ли элегантный способ сделать это?

Ответом является объявление create () extern "C" ... create .... Это прекрасно работает. Задача решена. Спасибо за вашу помощь и терпение.

Ответы [ 5 ]

4 голосов
/ 01 октября 2009

Вам необходимо использовать опцию компоновщика "export-dynamic" при компиляции вашего основного исполняемого файла.

Обычно основной исполняемый файл не экспортирует свои символы для использования динамическим компоновщиком (если только символ не используется какой-либо общей библиотекой, участвующей в ссылке), что означает, что если ваша библиотека перезванивает в основной исполняемый файл, она не удастся загрузить.

Это происходит неявно, когда вы пытаетесь создать подкласс класса с помощью виртуальных методов и в некоторых других случаях. Если вы попытаетесь это сделать, это не удастся.

Таким образом, при связывании вашей основной программы добавьте -Wl,-export-dynamic, она будет просто работать.

1 голос
/ 01 октября 2009

Должен ли я объявить create () как extern "C" void * create (void); и затем привести указатель void вместо прямой попытки связать символы c ++?

Лично я бы порекомендовал это, даже если это не настоящая проблема. Распределение имен является довольно стандартным в настоящее время среди UNIX-подобных ОС - как с Intel ABI и всеми остальными - но это не совсем стандарт, и Windows использует другую схему искажения имен (поэтому перенос приложения на Windows потребует изменения этих строк) , и я не уверен, есть ли OS X на плате (поэтому портирование на OS X может потребовать изменения этих строк).

1 голос
/ 01 октября 2009

Это может быть несоответствие в видимости символа _ZTI10BaseFilter (который является типовой информацией для класса) между вашим .so и приложением. Что вы получите, если вы запустите

nm <target> | grep _ZTI10BaseFilter

на каждом target, который включает BaseFilter, т.е. ваши динамические библиотеки и исполняемый файл?

1 голос
/ 01 октября 2009

Я столкнулся с этим в своем исследовании архитектуры плагинов. Ваша ошибка не в вашей основной, а в том, как вы связали libexamplefilter.so. К сожалению, у меня нет кода (или памяти!), Чтобы точно сказать, как его решить, но я думаю вам нужно объявить ваш класс BaseFilter в отдельном .so, и свяжите как libexamplefilter и ваше приложение с этим .so.

0 голосов
/ 01 октября 2009
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...