2017-02-16 10 views
0

申し訳ありませんが、長い投稿です。私はちょっと調べてみましたが、答えが見つかりませんでしたので、ここに行きます:WindowsのDLL境界にPython/C++コードが埋め込まれた状態でプログラムがクラッシュする

私はC++(BoostPython)を使ってPython拡張ライブラリを開発しています。テストのために私たちはPythonベースのテストハーネスを持っていますが、別のC++実行可能ファイル(BoostUnitTestなどを使用)を追加して、Pythonに直接公開されていない機能のテストを含むライブラリのテストを追加したいとします。

私は現在問題なくLinuxでこれを実行しています。私はライブラリを構築しており、これはBoostUnitTestを使用する実行可能ファイルに動的にリンクしています。すべてがコンパイルされ、期待通りに実行されます。 Windowsでは、私は問題を抱えています。私はそれがDLLの境界を越えてC++ - > Python型コンバータの登録に問題があると思う。マイライブラリでは、私が定義した :

DLL_APIは、Windows用の通常の_declspec(...)である
namespace bp = boost::python; 
namespace bn = boost::numpy; 

class DLL_API DummyClass 
{ 
public: 
    static std::shared_ptr<DummyClass> Create() 
    { 
     return std::make_shared<DummyClass>(); 
    } 
    static void RegisterPythonBindings(); 
}; 
void DummyClass::RegisterPythonBindings() 
{ 
    bp::class_<DummyClass>("DummyClass", bp::init<>()) 
     ; 

    bp::register_ptr_to_python< std::shared_ptr<DummyClass> >(); 
} 

を、私は、次の例を持っている問題を表示するには 。アイデアは、このダミーのクラスは、私は(の省略がなど、含み)は、ライブラリにリンクし実行可能ファイル内から

BOOST_PYTHON_MODULE(module) 
{ 
    DummyClass::RegisterPythonBindings(); 
} 

で大きなPythonモジュールの一部としてエクスポートされることである。

void main() 
{ 
    Py_Initialize(); 
    DummyClass::RegisterPythonBindings(); 
    auto myDummy = DummyClass::Create(); 
    auto dummyObj = bp::object(myDummy); 
} 

最後の行は、私はboost :: python :: object内でmyDummyをラップし、Windowsで未処理の例外が発生してクラッシュします。例外はPythonからスローされています(throw_error_already_set)。私はバインディングを登録するよう呼びかけたにもかかわらず、PythonにC++型の適切なコンバータを見つけられないと(私は間違っているかもしれない)と信じています。試験として

KernelBase.dll!000007fefd91a06d() 
msvcr110.dll!000007fef7bde92c() 
TestFromMain.exe!boost::python::throw_error_already_set(void) 
TestFromMain.exe!boost::python::converter::registration::to_python(void const volatile *) 
TestFromMain.exe!boost::python::converter::detail::arg_to_python_base::arg_to_python_base(void const volatile *,struct boost::python::converter::registration const &) 
TestFromMain.exe!main() Line 66 
TestFromMain.exe!__tmainCRTStartup() 
kernel32.dll!0000000077a259cd() 
ntdll.dll!0000000077b5a561() 

、私の代わりにDLLにリンクするだけでメイン関数の前にすべての実行内側DummyClassを定義する正確に同じコードをコピーし、そして予想通り、これは働きます。

私のモデルは、Windowsで可能な場合でも境界の両側に埋め込まれたpythonを使用してDLLとしてコンパイルされています(これはテストハーネスでのみ使用されるため、常に同じツールチェーンを使用します)。

ありがとうございました。

答えて

0

これを読んだことがある人にとっては、WindowsのソリューションはBoostをダイナミックライブラリとしてコンパイルし、すべてを動的にリンクすることでした。コードの構造を少し変更する必要がありましたが、現在は機能しています。

WindowsでBoostのダイナミックなlibバージョンには、Python/C +間の変換に使用されるタイプの共通レジスタが1つあるというBoostのマニュアルがあります。ドキュメントは、静的なlibバージョンの共通のレジスタを持っていないことに言及していない(しかし、私は今それが動作しないことを知っている)。

関連する問題