Страницы

Поиск по вопросам

Показаны сообщения с ярлыком разделяемые-библиотеки. Показать все сообщения
Показаны сообщения с ярлыком разделяемые-библиотеки. Показать все сообщения

четверг, 13 февраля 2020 г.

Что является аналогом DllMain в Linux?

#linux #gcc #разделяемые_библиотеки


Функция DllMain является дополнительной точкой входа в динамически подключаемую библиотеку.
BOOL WINAPI DllMain(
  __in  HINSTANCE hinstDLL,
  __in  DWORD fdwReason,
  __in  LPVOID lpvReserved
);

Каким образом можно в linux задать код, который будет подобным образом выполняться
при загрузке и выгрузке разделяемой библиотеки?    


Ответы

Ответ 1



Задать код, который будет выполняться при подключении и отключении библиотеки, можно, используя атрибуты gcc constructor и destructor. void start() __attribute__ ((constructor)); void finish() __attribute__ ((destructor)); void start() { // Выполнить до } void finish() { // Выполнить после }

пятница, 27 декабря 2019 г.

Обращение к *.so по относительному пути

#linux #c #разделяемые_библиотеки


Есть библиотека libsvsynth.so, идущая в комплекте с программой, которая её использует.
Т.к. библиотека не устанавливается в систему (программа задумывалась, как физически
переносимая), то к путь к ней в функции dlopen описывается как ./libsvsynth.so.

При использовании:

$ ./prog


Всё работает - библиотека подключается. Однако, если написать

$ ./parent_dir/prog


То библиотека программой обнаружена не будет (как я понял, библиотека будет искаться
в вызываемом каталоге)

Что же нужно сделать для того, чтобы программу можно было запускать без проблем из
любого места, а не только из каталога с бинарником+библиотекой?
    


Ответы

Ответ 1



наиболее простой вариант: скрипт-обёртка можете рядом с программой приложить скрипт примерно такого содержания: #!/bin/sh cd "$(dirname "$0")" && ./prog присвоить ему биты исполнимости: $ chmod +x путь/к/этому/скрипту и вызывать его из любого места файловой системы, указывая хоть относительный, хоть абсолютный путь. более сложный вариант: не линковать, а динамически подгружать нужную библиотеку в процессе работы программы, предварительно получив путь к выполняемому файлу и дополнив его путём к библиотеке.

Ответ 2



Развивая идею, предложенную в дополнении к ответу Александра Баракина, набросал пример функции, которая загружает динамическую библиотеку по пути файла, относительного текущего выполняемого файла вне зависимости от рабочего каталога или переменных окружения. void* load_library(const char* r_path) { if (r_path[0] == '/') return dlopen(r_path, RTLD_LAZY); char a_path[PATH_MAX] = {0}; readlink("/proc/self/exe", a_path, sizeof a_path); char* last_slash = strrchr(a_path, '/'); if (last_slash == NULL) { // в иных Unix-системах надо по-другому определять текущий бинарник errno = ENOSYS; return NULL; } strcpy(last_slash + 1, r_path); return dlopen(a_path, RTLD_LAZY); }

Ответ 3



При работе с библиотеками можно использовать возможности компилятора и указать путь где будет происходить поиск библиотеки gcc -Wl,rpath,/usr/local/lib если нет возможности слинковать программу с нужными путями можно использовать переменую LD_LIBRARY_PATH=/usr/local/lib указав в ней пути поиска библиотеки.

Ответ 4



Итак, проблема была решена следующим образом: к программе всё же пришлось добавить shell-скрипт (start.sh) следующего содержания: #!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" cd $DIR ./prog $@ Затем делаем chmod +x ./start.sh и запускаем из любого каталога в системе

понедельник, 26 ноября 2018 г.

Обращение к *.so по относительному пути

Есть библиотека libsvsynth.so, идущая в комплекте с программой, которая её использует. Т.к. библиотека не устанавливается в систему (программа задумывалась, как физически переносимая), то к путь к ней в функции dlopen описывается как ./libsvsynth.so
При использовании:
$ ./prog
Всё работает - библиотека подключается. Однако, если написать
$ ./parent_dir/prog
То библиотека программой обнаружена не будет (как я понял, библиотека будет искаться в вызываемом каталоге)
Что же нужно сделать для того, чтобы программу можно было запускать без проблем из любого места, а не только из каталога с бинарником+библиотекой?


Ответ

Итак, проблема была решена следующим образом: к программе всё же пришлось добавить shell-скрипт (start.sh) следующего содержания:
#!/bin/bash SOURCE="${BASH_SOURCE[0]}" while [ -h "$SOURCE" ]; do DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" SOURCE="$(readlink "$SOURCE")" [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" done DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" cd $DIR ./prog $@
Затем делаем chmod +x ./start.sh и запускаем из любого каталога в системе