Как разрешить неразрешенный символ?

#c #dynamic-linking

#c #динамическое связывание

Вопрос:

Приветствую.

У меня возникла проблема с динамическим связыванием моей библиотеки с моей программой. Вот что происходит: я разрабатываю модульную программу и тестирую модульную систему. Дело в том, что мои модули используют некоторый класс, который определен в основном двоичном файле: несколько абстрактных классов, которые не вызывают никаких проблем, и очень конкретный класс, который просто не может быть разрешен.

Я использую набор функций dlopen / dlsym / dlclose. И я компилирую, используя g .

Дело в том, что если я попрошу dlopen загрузить все символы, то он не сообщит мне об этом "undefined symbol: _ZNK3zia3api8DataTreecvRKSsEv Но если я запущу dlopen в отложенном режиме, это произойдет только при первом использовании так называемого класса (и сразу после этого произойдет сбой).

Итак, это класс «DataTree», и я хочу сделать его доступным как для основного двоичного файла, так и для модулей. Я уже пытался скомпилировать его в каждом из двоичных файлов: как я и ожидал, это не сработало. Я также пытался сделать его полностью встроенным, но это так же бесполезно, как и моя другая попытка. Я попытался скомпилировать основной двоичный файл с опцией «-rdynamic». Изменений нет.

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

Я компилирую объекты модуля с опцией -fPIC, вот так :

 g   -Wall -fPIC -c mysource.cpp
  

И затем я использую эту строку для создания библиотеки :

 g   -shared -Wl,-soname,mylib.so.1 -o mylib.so mysource.o
  

Я полагаю, лучшим решением было бы не компилировать объект в библиотеке, а сделать символ доступным из основного двоичного файла.
Итак, вопрос в том, как это сделать? (и это то, что я должен делать?)

Комментарии:

1. искаженное имя — zia::api::DataTree::operator std::string constamp;() const

2. Вы можете получить (в Linux) исправленное имя с помощью c filt утилиты. Вызов — это просто c filt _ZNK3zia3api8DataTreecvRKSsEv , а результат — это то, что опубликовал @Industrial. Очень удобно!

3. Боже милостивый! Это действительно не определено! Я этого не заметил! Большое спасибо!

4. @Matthieu M.: в c filt написано «zia:: api::DataTree::operator std::basic_string<char, std::char_traits<char>, std::allocator<char> > constamp;() const», но я использовал abi::__cxa_demangle из #include <cxxabi.h>

5. @Industrial: верно, std::basic_string бит может быть немного пугающим:p

Ответ №1:

Попробуйте добавить -rdynamic в библиотечный модуль не основную программу и убедитесь, что все ваши классы, которые имеют виртуальные методы и наследуются, имеют виртуальный деструктор. Еще одно предложение: создайте минимальный пример и разместите его здесь.

Комментарии:

1. Вызывающий его класс не имеет никакого виртуального метода, кроме своего деструктора. Я также проверил: я уже использую -rdynamic, и теперь делаю это как для основного двоичного файла, так и для библиотеки (на всякий случай). По-прежнему никаких изменений :/ !