Подтвердить что ты не робот

Получать ошибку "undefined" при загрузке библиотеки с помощью dlopen

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

Моя командная строка для создания разделяемых библиотек выглядит так:

cc -shared -fPIC -o module.so -g -Wall module.c

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

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

Мой вызов dlopen выглядит следующим образом:

void *handle = dlopen(plugin, RTLD_NOW);

Кто-нибудь может посоветовать, как мой модуль может вернуться к моему исполняемому файлу, без необходимости включать все исполняемые служебные функции в еще одну общую библиотеку?

4b9b3361

Ответ 1

Я сам нашел ответ.

Мне пришлось добавить флаги --export-dynamic к параметрам ссылок для основного исполняемого файла.

При создании динамически связанных исполняемый файл, добавьте все символы в динамическая таблица символов. Динамический таблица символов - это набор символов которые видны из динамических объектов во время выполнения.

Если вы не используете эту опцию, таблица динамических символов обычно содержат только те символы, которые ссылка на какой-либо динамический объект упомянутых в ссылке.

Если вы используете "dlopen" для загрузки динамического объект, который должен символы, определенные программой, а не какой-либо другой динамический объект, то вам, вероятно, понадобится использовать этот параметр при связывании программы сам по себе.

Ответ 2

Правильное решение - добавить -rdynamic в команду связи основного исполняемого файла. Это добавит соответствующую опцию ld (которая при использовании GNU ld оказывается --export-dynamic).

Добавление --export-dynamic напрямую технически неверно: это вариант компоновщика, и поэтому его следует добавить как -Wl,--export-dynamic или -Wl,-E. Это также менее переносимо, чем -rdynamic (другие линкеры имеют эквивалент, но сам вариант отличается).

Ответ 3

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

dlopen(NULL,RTLD_NOW|RTLD_GLOBAL);

Я думаю, что решение лучше. Причина в том, что он также решает ту же проблему, если вы

a) ваша программа (или модуль третьей стороны) связана (не во время выполнения) с общей библиотекой, какие символы должны быть в динамической таблице;

b) не может перекомпилировать этот модуль с флагом -rdynamic.