10

オープンソースのアカデミック コードを動作させようとしています (プロジェクトのホームはこちらです)。これは、(非常に) 薄い python ラッパーを備えた大きな C++ コードベースでありCDLL、C++ をロードし、コードのプリミティブ python スクリプトを可能にするために使用できるいくつかの C 関数を呼び出すために使用されます。

ただし、最初のインポート コードは、サイト パッケージ内の隣にある .so ファイルを見つけることができないため、クラッシュします。

インストールされたファイルで:

from ctypes import *

try:
  self.lib = CDLL("_lammps.so")
except:
  try:
    self.lib = CDLL("_lammps_serial.so")
  except:
    raise OSError,"Could not load LAMMPS dynamic library"

そしてスクリプトまたはインタープリターで:

from lammps import lammps
l = lammps()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lammps.py", line 42, in __init__
    raise OSError,"Could not load LAMMPS dynamic library"
OSError: Could not load LAMMPS dynamic library

他の回答ではこれがカバーされているように見えるかもしれませんが、これは、実際に呼び出されたスクリプト (またはインタープリターを実行したプロンプトの作業ディレクトリ) 内で呼び出された場合にのみ機能CDLL()します。つまり、「相対パス」がユーザー空間ではなく、 python-ライブラリ-スペース。

自分で構築した C/C++ ライブラリをインポートするために確実にインストールするにはどうすればよいですか? のようなシステムライブラリの場所を汚染する/usr/libことを除いて、これはあまりpythonicではありませんが、簡単な解決策がわかりません。

(編集:関数名を修正、不明確なリファクタリングは役に立たない!申し訳ありません!)

4

5 に答える 5

2

__file__インポートを行っているパッケージで変数を使用できます。のさまざまな関数を使用してos.pathから完全な絶対ディレクトリ パスを抽出し、__file__それをライブラリ ファイル名に結合するだけです。何かのようなもの:

temp = os.path.abspath(__file__)
temp = os.path.realpath(temp)
temp = os.path.dirname(temp)
temp = os.path.join(temp, "_lammps.so")
lib = CDLL(path)

プラットフォームに依存しないようにしたい場合は、コアファイル名のさまざまなバリエーションを試してみることもできます (つまり、の.dll有無にかかわら.dylib.so、接頭辞の有無、バージョン番号の追加など)。libそのようなものを生産します。次に、いくつかのバージョンを試すか、単に を使用glob.globして許容できるバージョンを見つけることができます。

標準ライブラリにそのような関数が存在しないのはおかしいと言わざるを得ません。は、このctypes.util.find_library種の使用には十分な柔軟性 (または徹底したもの) ではありません (広く使用されていると思います)。ファイルを検索する関数だけでもPYTHONPATH非常に便利でした (書くのは難しくありませんが)。

繰り返しますが、正しいディレクトリを に追加するだけで、それをロードLD_LIBRARY_PATHできるはずです。

于 2013-05-07T08:52:58.303 に答える
2

strace -eopen で実行すると、次のように表示されます。

open("tls/x86_64/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("tls/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("x86_64/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("_lammps.so", O_RDONLY|O_CLOEXEC)  = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 6
open("/lib/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/_lammps.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)

これにより、python ctypes がライブラリを検索するすべての場所が表示されます。これまでのところ、システムに検索場所を追加するためのランタイム環境変数の微調整を見つけることができませんでした。おそらく絶対パスを使用する必要があります。

于 2012-02-06T12:15:57.763 に答える