2015-10-15 25 views
0

是否有任何編程方式來獲取程序加載的動態庫的位置?在C++(linux)中獲取動態庫目錄

我知道有可能得到'可執行的'運行路徑。但這對我來說還不夠。

我正在開發一個外部庫,有一些依賴關係,我需要相應地指向它的位置。

例如,程序在運行:

/local/deepLearning/bin 

而這個程序使用位於一個動態庫:

/local/external/libs/faciesAnalysis 

我需要的是,在運行時,該字符串

"/local/external/libs/facesAnalysis" 

我在linux上工作,有什麼建議嗎?

+0

某些版本的linux爲此提供了額外的dlopen支持。 – bmargulies

+0

看看這個重複的問題[如何獲得加載共享庫的路徑在Linux上的C程序?](http://stackoverflow.com/questions/32934274/how-to-get-paths-of-loaded- linux-shared-libraries-in-ac-program-on-linux) –

+0

http://syprog.blogspot.ru/2011/12/listing-loaded-shared-objects-in-linux.html –

回答

0

你可以得到完整的可執行文件路徑(std::string path_and_exe),然後執行以下命令:

#include <cstdlib> 
std::string output("output.txt"); 

system ("ldd " + path_and_exe + " > " + output); 

// read libray paths from output file 
+0

至少建議一個'popen',但實際上這並不是非常需要。只需使用我的答案建議的'/ proc/self/maps'(更快,對外部資源的依賴性更低) –

+0

@BasileStarynkevitch非常匆忙,看到沒有人幫助OP,因此解決了第一個(相當糟糕的)解決方案頭腦 –

1

首先(這是具體到Linux,因爲內核提供的),你可以分析/proc/self/maps僞文件從你的程序中。只要按順序讀取該文本文件的每一行,就可以獲得每個mmap -ed文件的完整路徑,包括共享庫。請參閱proc(5)(並使用dirname(3)從路徑中獲取目錄,也可能是realpath(3) ...)。還閱讀dlopen(3) & ld-linux.so(8)和注意的LD_LIBRARY_PATH/etc/ld.so.conf

則角色,這是特定於GNU libc(但顯然musl-libc也有),你可以在某些函數地址使用dladdr(3)從該庫。或者只是使用dl_iterate_phdr(3),這看起來完全適合您的問題。

提防怪異的情況:某些程序可能會產生一個插件,dlopen後來(我MELTthat),其他一些程序可能remove插件dlopen後,某些程序可能會被靜態鏈接,該dlopen -ed該插件會已被移動或重命名(也許是因爲你的程序運行時的新版本已經安裝)......,同樣的插件可能已被符號鏈接和dlopened使用不同的路徑,等等

閱讀Drepper的論文:How To Write Shared Libraries

0

爲什麼你需要這個紋理NG?你有沒有特別想做的事?例如,加載位於同一目錄中的另一個庫,這不是正確的方法。你能給更多的上下文嗎?

+0

這應該是一個評論,而不是一個答案。 –

+0

應該是一個評論。但我同意你,@mogeb,認識JoãoPaulo的實際最終目標將導致他接受最好的建議 – pestophagous