2009-05-13 14 views
29

実行時にこの環境変数を更新すると、どのようにctypesがライブラリをロードできますか?私は以下を試してみたが、どちらもうまくいかない。 Pythonなどのプログラムが実行されるまでに実行時に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") 

答えて

35

、ダイナミック・ローダー(ld.so.1のまたは類似のもの)が既にLD_LIBRARY_PATHを読み出したとその後の変更に気付かないであろう。したがって、Pythonソフトウェア自体がLD_LIBRARY_PATHを評価し、それを使用してdlopen()のライブラリの可能なパス名またはそれに相当する関数を作成しない限り、スクリプト内の変数を設定しても効果はありません。

あなたはそれがうまくいかないと言うと、Pythonはすべての可能なライブラリ名をビルドして試していないと思われるようです。たぶんLD_LIBRARY_PATHのみに依存しています。

+5

のような他の動的ライブラリも見つけますが、これは問題を診断しますが解決しません。 – dbliss

13

CDLLには完全修飾パス名を渡すことができます。たとえば、私のスクリプトの中で、.soがpythonスクリプトと同じディレクトリにある場合、次のものを使用しています。

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

あなたの場合、次のようにすれば十分です。あなたがCDLLまたはcdll.LoadLibrary(完全修飾パスを与える場合であっても

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

)、あなたはまだ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」のdoesnのため、私は、第二の負荷にエラーが発生しますそれが正しいことを知っている。ですから、事前にLD_LIBRARY_PATHを設定して '/ abs/path/to'を含める必要があります。

LD_LIBRARY_PATHを設定する必要がないようにするには、.soファイルのrpathエントリを変更します。 Linuxでは、chrpathとpatchelfの2つのユーティリティがあります。 chrpathはUbuntuリポジトリから入手できます。それは一度もなかった.soのrpathを変更することはできません。 patchelfはより柔軟です。

1

のような現在の作業ディレクトリへのRPATH相対であなたのバイナリをコンパイルします。このよう

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

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

はその後、あなたがして、実行時にPythonで作業ディレクトリを変更することができますローダーはotherbinary.so

+0

これは、ライブラリをロードするプロセスの作業ディレクトリがライブラリのディレクトリである場合にのみ機能します。それ以外の場合、相対実行時パスは依存関係を見つけることができません。依存関係はディレクトリがライブラリに対して相対的です。 – danny

関連する問題