#linker #shared-libraries #dynamic-linking #dlopen
Вопрос:
У меня есть библиотека с закрытым исходным кодом, в которой есть функция, которую мне нужно вызвать через dlsym (это часть драйвера, который я пишу, и единственный способ управлять оборудованием-вызывать функции в этой библиотеке с закрытым исходным кодом), и она ссылается на другую функцию в другой библиотеке, которая загружает информацию о конфигурации. Возможно ли, чтобы функция, которую я вызываю в библиотеке, вызывала мою собственную функцию для загрузки информации о конфигурации? Вот иллюстрация кода того, что я пытаюсь сделать (для краткости я пропустил объявление переменных):
int main(int argc, char** argv) { library = dlopen("/usr/local/lib/libuLinux_hal.so", RTLD_LAZY); func_point = dlsym(library, "ec_sys_set_fan_speed"); func_point(arg1, arg2); // Makes a call to Ini_Conf_Get_Field_Int and does other stuff } int Ini_Conf_Get_Field_Int(int arg) { // Do stuff return 0; }
Функция ec_sys_set_fan_speed в libuLinux_hal.so библиотека вызывает функцию с именем Ini_Conf_Get_Field_Int (которая находится в другой библиотеке). Я хотел бы как-то сказать динамическому компоновщику, чтобы вместо этого он вызывал мою собственную функцию Ini_Conf_Get_Field_Int в моей программе. Возможно ли это?
Редактировать: основываясь на ответе русского языка, я изменил свое заявление о компиляции, чтобы оно было:
cc -o qnap-ec qnap-ec-helper.c -Wall -O2 -ldl -Wl,--export-dynamic-symbol=Ini_Conf_Get_Field_Int
однако я получаю следующую ошибку:
/usr/bin/ld: warning: cannot find entry symbol xport-dynamic-symbol=Ini_Conf_Get_Field_Int; defaulting to 00000000000011c0
В случае, если это полезно, моя информация о версии ld
GNU ld (GNU Binutils for Ubuntu) 2.34
Ответ №1:
Возможно ли это?
ДА.
Вам нужно сделать две вещи, чтобы это сработало:
- определите
Ini_Conf_Get_Field_Int()
функцию в вашей основной программе (вы уже делаете это) и - сделайте эту функцию экспортированной в таблицу динамических символов (видимой в выходных данных
nm -D a.out | grep ' Ini_Conf_Get_Field_Int$'
).
Вероятно, вы пропустили шаг 2.
Чтобы выполнить шаг 2, используйте -Wl,--export-dynamic
флаг при связывании основного исполняемого файла.
Если ваш компоновщик поддерживает --export-dynamic-symbol
флаг, лучшим решением является использование -Wl,--export-dynamic-symbol,Ini_Conf_Get_Field_Int
.
Комментарии:
1. Использование -export-dynamic работает, однако, когда я использую-export-dynamic-символ,Ini_Conf_Get_Field_Int я получаю следующую ошибку компоновщика: не удается найти символ ввода xport-dynamic-символ,Ini_Conf_Get_Field_Int; значение по умолчанию 00000000000011c0
2. @HarryMuscle Вы, кажется, пропустили
-Wl,
впереди--export-dynamic-symbol
.3. Извините, я удалил это из своего комментария для краткости, флаг полного компоновщика точно такой, как вы упомянули: -Wl,—экспорт-динамический символ,Ini_Conf_Get_Field_Int
4. @HarryMuscle Я не уверен, что верю тебе. Пожалуйста, отредактируйте свой вопрос с помощью точной команды и точного вывода ошибок. Также, пожалуйста, покажите вывод из
ld --version
.5. Как и просил, я добавил детали к своему первоначальному вопросу.