簡體   English   中英

在運行時更改 ctypes 的 LD_LIBRARY_PATH

[英]Changing LD_LIBRARY_PATH at runtime for ctypes

你如何在運行時更新這個環境變量,以便 ctypes 可以在任何地方加載庫? 我嘗試了以下方法,但似乎都不起作用。

from ctypes import *
os.environ['LD_LIBRARY_PATH'] = "/home/starlon/Projects/pyCFA635/lib"  
os.putenv('LD_LIBRARY_PATH', "/home/starlon/Projects/pyCFA635/lib")  
lib = CDLL("libevaluator.so")

當 Python 等程序運行時,動態加載器(ld.so.1 或類似的東西)已經讀取了 LD_LIBRARY_PATH 並且此后不會注意到任何更改。 因此,除非 Python 軟件本身評估 LD_LIBRARY_PATH 並使用它來構建dlopen()或要使用的等效函數的庫的可能路徑名,否則在腳本中設置變量將不起作用。

鑒於您說它不起作用,假設 Python 不會構建並嘗試所有可能的庫名稱似乎是合理的; 它可能僅依賴於 LD_LIBRARY_PATH。

即使您提供 CDLL 或 cdll.LoadLibrary() 的完全限定路徑,您可能仍需要在調用 Python 之前設置 LD_LIBRARY_PATH。 如果您加載的共享庫顯式引用了另一個共享庫,並且沒有在 .so 中為該庫設置“rpath”,那么即使它已經被加載,也不會被找到。 庫中的 rpath 指定用於搜索該庫所需的其他庫的搜索路徑

比如我有一個案例,一組不是我自己制作的相互依賴的第三方庫。 b.so 引用 a.so。 即使我提前加載 a.so:

ctypes.cdll.LoadLibrary('/abs/path/to/a.so')
ctypes.cdll.LoadLibrary('/abs/path/to/b.so')

我在第二次加載時遇到錯誤,因為 b.so 僅指代“a.so”,沒有 rpath,因此 b.so 不知道那是正確的 a.so。 所以我必須提前設置 LD_LIBRARY_PATH 以包含'/abs/path/to'。

為了避免設置 LD_LIBRARY_PATH,您可以修改 .so 文件中的 rpath 條目。 在 Linux 上,我發現有兩個實用程序可以執行此操作: chrpath 和patchelf chrpath 可從 Ubuntu 存儲庫中獲得。 它無法更改 .so 上從未有過的 rpath。 patchelf 更靈活。

CDLL 可以傳遞一個完全限定的路徑名​​,因此例如我在我的腳本之一中使用以下內容,其中 .so 與 python 腳本位於同一目錄中。

import os
path = os.path.dirname(os.path.realpath(__file__))
dll = CDLL("%s/iface.so"%path)

在您的情況下,以下內容就足夠了。

from ctypes import *
lib = CDLL("/home/starlon/Projects/pyCFA635/lib/libevaluator.so")

使用相對於當前工作目錄的 rpath 編譯二進制文件,例如:

gcc -shared -o yourbinary.so yoursource.c otherbinary.so \
    -Wl,-rpath='.',-rpath='./another/relative/rpath' -fpic

然后,您可以在運行時更改 python 中的工作目錄:

import os
os.chdir('/path/to/your/binaries')

像這樣,加載器也找到了其他動態庫,比如otherbinary.so

將 LD_LIBRARY_PATH 設置為放置庫的路徑在此處不起作用,並且 ctypes 不會注意到任何更改。 因此,您需要在源代碼中設置它並在腳本之前運行 ldconfig 以將其考慮在內。 此外,在腳本中設置 os 環境或任何 PATH 變量將不起作用。

我遇到了類似的問題,花了大約一天的時間來解決這個問題。

mkdir -p /etc/ld.so.conf.d/
echo "/home/starlon/Projects/pyCFA635/lib" > /etc/ld.so.conf.d/mycustomPath.conf

ldconfig

然后驗證路徑是否設置為:

ldconfig -v | less

完成后,嘗試運行您的腳本。 這對我有用,也應該對你有用。

您可以在下面看到幫助我解決此問題的 URL:

https://www.cyberciti.biz/faq/linux-setting-changed-library-path/

注意:我意識到這個問題很舊,但是我想為此做出貢獻,因為僅接受的答案實際上並不能解決我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM