Я использую C ++ dlopen (), чтобы связать совместно используемую библиотеку с именем lib * .so (в каталоге A) в моей основной программе (в каталоге B).
Я экспериментировал над загрузкой некоторых простых функций,Все работает очень хорошо.Тем не менее, это доставило мне головную боль, когда я пытался загрузить функции класса и фабрики, которые возвращают указатель на объект класса.(Я использую термины из учебника ниже)
Методология, которую я использовал, была основана на примерах в главе 3.3 этого урока https://www.tldp.org/HOWTO/C++-dlopen/thesolution.html#externC.
Здесь есть немного полиморфизма... lib * .so содержит дочерний класс, который наследует родительский абстрактный класс из основного каталога программы (каталог B).Когда dlopen () пытается загрузить lib * .so в основную программу, происходит сбой из-за «неопределенного символа».
Я использовал команду nm для проверки таблиц символов в lib * .so и двоичном коде основной программы.Символы в этих двоичных файлах:
lib * .so: U _ZTI7ParentBox
двоичный файл основной программы: V _ZTI7ParentBox
ParentBox - это имя родительского класса, унаследованного ChildBox в lib *.так.Обратите внимание, что файл заголовка родительского класса находится в другом проекте в каталоге B.
Несмотря на то, что имя искажает имена символов, они точно такие же.Мне просто интересно, почему динамический компоновщик не может связать их?и дает мне непонятную ошибку символа для dlopen ()?
Мне не хватает понимания некоторых ключевых понятий здесь?
PS еще более странно, что он смог разрешить символы для функций-членов между дочерним классом (символ типа U) в lib * .so (символ типа T) и родительским классом.Почему он может это сделать, но не может разрешить неопределенный символ для имени родительского класса?
(Я долго искал и пробовал -rdynamic, -ldl, хотя я неполностью понял, что они есть, но ничего не помогло)
Обновление 04 апреля 2019 года: Это командная строка g ++, которую я использовал, чтобы сделать основную программу двоичной.
g++ -fvisibility=hidden -pthread -static-libgcc -static-libstdc++ \
-m64 -fpic -ggdb3 -fno-var-tracking-assignments -std=c++14 \
-rdynamic \
-o ./build/main-prog \
/some_absolute_path/ParentBox.o \
/some_other_pathen/Triangle.o \
/some_other_pathen/Circle.o \
/some_other_pathen/<lots_of_depending_obj> \
/some_absolute_path/librandom.a \
-lz -ldl -lrt -lbz2
Я искал каждый аргумент этой командной строки в https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html (Это хороший справочный сайт для всех коллег-программистов, работающих с большими проектами со сложной строкой g ++ :))
Спасибо @ Занятым русским .С его указаниями проблема сужается для экспорта символов в двоичный файл основной программы.
Однако двоичный файл основной программы имеет множество зависимостей, как вы можете видеть из приведенной выше команды, Circle, Triangle и множества других объектных файлов.Нам также нужно добавить «-rdynamic» к компиляции Circle, Triangle и других объектных файлов зависимостей.В противном случае это не работает.
В моем случае я добавил «-rdynamic» ко всем файлам в моем проекте, чтобы экспортировать все символы.Не уверен, что "-fvisibility = hidden" делает что-то хорошее.В любом случае я удалил все из них в своем Makefile ... Я знаю, что это не лучший способ, но я буду беспокоиться о скорости позже, когда все будет функционально правильно.:)
Больше обновлений: Правильное решение в обновлении @Employed Russian в ответе.Мое предыдущее решение сработало, потому что я также удалил «-fvisibility = hidden».Нет необходимости (и, вероятно, неправильно) добавлять -rdynamic ко всем объектам, используемым в последней ссылке.Пожалуйста, обратитесь к объяснению @Employed Russian, которое решает основную проблему.
Окончательное обновление: Для коллег-программистов, которые интересуются тем, как выполняется программа на C / C ++ и как можно связать библиотеку, вот хороший справочный веб-курс (Life of Binary) от XenoKovah: http://opensecuritytraining.info/LifeOfBinaries.html
Вы также можете найти плейлист на YouTube.Просто поиск "Бинарная жизнь"