2017-04-20 48 views
0

SQLAPI ++有一個不尋常的功能,可以在其中設置一個字符串以告訴它在哪裏可以找到ODBC共享庫。在我的情況下,這是libtdsodbc.so,我的應用程序實際上在構建時鏈接了該庫,但在運行時,這不足以使SQLAPI ++正常工作。SQLAPI ++:獲取由可執行文件加載的共享庫的路徑

我的代碼是:

SAConnection conn; 
    conn.setOption("ODBC.LIBS") = "libtdsodbc.so"; 
    conn.Connect("SERVER=...", "", "", SA_ODBC_Client); 

ODBC.LIBSdocumented這樣的:

部隊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 ++之外)通過RUNPATH發現libtdsodbc.so,這是在構建時設置的。此路徑不是像/usr/lib這樣的系統路徑。我想讓SQLAPI ++使用運行時在應用程序中加載的相同庫。

一個想法是應用到inspect its own RUNPATH,搜索libtdsobc.so,並使用該路徑。但是這需要相當多的代碼來基本上重新實現ld.so已經做了什麼。

我不想在構建時刻將可執行文件的路徑與RUNPATH分開,因爲在部署之前我有時會編輯RUNPATH(然後我需要編輯兩件事)。

理想情況下,我想告訴SQLAPI ++只使用已加載的庫。我可以通過運行lsof -p PID | grep libtdsodbc.so來確定這條路徑,但是從可執行文件中運行shell命令並不是一個好的解決方案(並且我寧可不執行lsof)。

回答

1

您可以使用dl_iterate_phdr(該鏈接還包括打印出lib名稱的示例代碼)或手動解析/proc/self/maps

相關問題