Скажите Динамическому Компоновщику, Чтобы Он Вызывал Мою Функцию Вместо Функции В Другой Общей Библиотеке

#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:

Возможно ли это?

ДА.

Вам нужно сделать две вещи, чтобы это сработало:

  1. определите Ini_Conf_Get_Field_Int() функцию в вашей основной программе (вы уже делаете это) и
  2. сделайте эту функцию экспортированной в таблицу динамических символов (видимой в выходных данных 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. Как и просил, я добавил детали к своему первоначальному вопросу.