2

SWIGを使用してPythonラッパーを作成したライブラリがあります。ライブラリ自体は、動的にリンクされている.soファイルにあるユーザー提供の関数を受け入れます。現在、私は自分で作成したものを扱っており、動的リンクをC++で機能させることができました。Pythonで実行しようとすると、未定義のシンボルエラーが発生します。これらのシンボルは、提供された.soファイルには存在しないが、メインプログラムには存在するシンボルです(基本的に、これらのシンボルは、提供されたモジュールがメインプログラムからのデータにアクセスできるようにする関数です)。

C ++で短いテストプログラムを実行してもエラーは発生しませんが、このラッパー(以前は機能していました)を使用したPythonでの短いテストプログラムは失敗します。PythonではなくC++で失敗する理由についての説明は考えられません。私が少し心配しているのは、C ++が正しく機能していないが、私に伝えていないという考えです。Pythonは、C++が機能していないというエラーを検出しています。それでも、C ++によって返される結果は正確であるため、これはありそうにないようです。

これがどのように可能であり、したがってどのように修正できるかについての考えはありますか?

ありがとう。

更新:このコードをプログラムの先頭に追加しました:

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)

これによりランタイムエラーが解消されますが、残念ながら2番目の問題が発生する可能性があります(リンクが原因です)。メインプログラムの一部であるダイナミックリンクライブラリ内から呼び出されている関数は、正しい値を返していません。それらは0を返しています。さらに、それらがまったく実行されていないことは明らかです。問題は、実際に何が実行されているのか、なぜそれがC ++と異なるのか、そしてそれをどのように修正するのかということです。

再度、感謝します。

更新-潜在的により明確な説明Pythonは、SWIGによってラップされた私のC++ライブラリであるモジュールをインポートします。このC++ライブラリは、dlopenとdlsymを使用して、ユーザーが指定した.soファイルから関数を取得します。ユーザーは、その仕事をするために、C++ライブラリの一部である関数へのファイル呼び出しを提供しました。.soファイルからC++ライブラリへの関数呼び出しは失敗している部分です。つまり、関数の呼び出しに失敗し、単に0を返します。ただし、この失敗は、テストコードがPythonで記述されている場合にのみ発生します。ライブラリを使用するC++テストコードは正常に機能します。

4

2 に答える 2

2

解決策は、PythonがグローバルスコープでC++メインライブラリをプリロードしていることを確認することです。これはあまり洗練された解決策ではなく、私はそれをやりたくありませんが、今のところはうまくいきます。

ここを少し覗いて、SWIGされたメインのC ++ライブラリを見つけるためにターミナルを起動するたびに設定する必要があるLD_LIBRARY_PATH環境変数を認識した後、LD_PRELOAD環境変数に気づきました。これをメインC++ライブラリのファイル名に設定すると、プログラムは機能しました。

これは、「他の共有ライブラリの関数を選択的にオーバーライドするために使用できる」ためだと思います。

環境変数を設定するよりも良い答えを誰かが思いついた場合、これがどれほど移植性があるかわからないので、それは素晴らしいでしょう。

編集:元の問題は、ユーザーが提供したライブラリが探している関数がグローバルスコープにないことです。これを修正するには、Pythonの「dl.open」を使用してメインライブラリの.soファイルを開き、dl.RTLD_NOWとdl.RTLD_GLOBALを使用します。

成功!

于 2010-08-05T09:10:57.750 に答える
1

Pythonインタープリターは、他のダイナミックリンクライブラリでシンボルを使用できるようにすることなく、ラッパー.soをロードしている可能性があります(シンボルの競合を回避するため)。ラッパーをインポートする直前に、次の行を追加してみてください。

import dl
sys.setdlopenflags(dl.RTLD_NOW | dl.RTLD_GLOBAL)
于 2010-08-03T16:32:18.820 に答える