ctypesのために、実行時にLD_LIBRARY_PATHを変更します
質問
どのようにして、実行時にこの環境変数を更新していますか?私は次のことを試したし、どちらが動作するようには思えません。
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はRPATHせずに、単に「a.so」を意味し、そのためb.soそれは正しいa.so.だ知らないので、私は、第二の負荷にエラーが発生しますだから私は「/ ABS /パス/に」が含まれるように、事前にLD_LIBRARY_PATHを設定する必要があります。
あなたが.soのファイルでRPATHエントリを変更、LD_LIBRARY_PATHを設定することを避けるために。 chrpath、および patchelf の:Linuxでは、私はこれを行う見つかった2つのユーティリティがあります。 chrpathは、Ubuntuのリポジトリから入手可能です。これは、1つを持っていなかったの.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 の
のような他の動的ライブラリを検索します