SQLAPI++: получение пути к общей библиотеке, загруженной исполняемым файлом
SQLAPI++ имеет необычную функцию, в которой вы задаете строку, указывающую, где искать разделяемую библиотеку ODBC. В моем случае это libtdsodbc.so
и мое приложение фактически связывает эту библиотеку во время сборки, но во время выполнения этого недостаточно для работы SQLAPI++.
Мой код:
SAConnection conn;
conn.setOption("ODBC.LIBS") = "libtdsodbc.so";
conn.Connect("SERVER=...", "", "", SA_ODBC_Client);
ODBC.LIBS
задокументировано так:
Принудительно использует библиотеку SQLAPI++ для использования указанной библиотеки диспетчера ODBC.
Приведенный выше код работает, если вы установите LD_LIBRARY_PATH
в каталог, содержащий libtdsodbc.so
, Но если вы этого не сделаете, Connect()
терпит неудачу:
libtdsodbc.so: cannot open shared object file: No such file or directory
DBMS API Library 'libtdsodbc.so' loading fails
This library is a part of DBMS client installation, not SQLAPI++
Make sure DBMS client is installed and
this required library is available for dynamic loading
Linux/Unix:
1) The directories in the user's LD_LIBRARY_PATH environment variable
2) The list of libraries cached in /etc/ld.so.cache
3) /usr/lib, followed by /lib
Это работает снова, если вы установите ODBC.LIBS
на полный путь, а не просто имя файла. Но как приложение может узнать, какой путь?
Мое приложение (за пределами SQLAPI++) находит libtdsodbc.so
через его RUNPATH
который устанавливается во время сборки. Этот путь не является системным путем, как /usr/lib
, Я хотел бы, чтобы SQLAPI++ использовал ту же библиотеку, которая загружается в приложение во время выполнения.
Одна из идей заключается в том, что приложение проверяет свою собственнуюRUNPATH
, ищи libtdsobc.so
и использовать этот путь. Но это требует довольно много неуклюжего кода, чтобы в основном переопределить то, что ld.so
уже делает.
Я не хочу запекать путь в исполняемый файл во время сборки отдельно от RUNPATH
потому что я иногда редактирую RUNPATH
перед развертыванием (а затем мне нужно отредактировать две вещи).
В идеале я хотел бы сказать SQLAPI++ просто использовать библиотеку, которая уже загружена. Я могу понять этот путь, запустив lsof -p PID | grep libtdsodbc.so
но запуск команд оболочки из исполняемого файла не является хорошим решением (и опять же, я бы предпочел не переопределять lsof
).
1 ответ
Вы можете использовать dl_iterate_phdr (ссылка также включает в себя пример кода, который печатает имена библиотек) или выполнить синтаксический анализ вручную. /proc/self/maps
,