2

図のように、PythonコールバックをC++ライブラリに追加しようとしています。

template<typename T> void doCallback(shared_ptr<T> data) {
   PyObject* pyfunc; //I have this already
   PyObject* args = Py_BuildValue("(O)", data);
   PyEval_CallObject(pyfunc,args);
}

データがswigを通過しておらず、PyObjectではないため、これは失敗します。

私は使ってみました:

swigData = SWIG_NewPointerObj((void*)data, NULL, 0);

ただし、テンプレートであるため、2番目のパラメーターに何を使用すればよいかわかりません。'正しい'SWIGTYPEをハードコーディングしても、通常はPyEval_CallObjectでsegfaultが発生します。

だから私の質問は:

  1. スウィッグタイプのラッピングを呼び出すための最良の方法は何ですか?

  2. 私もここで正しい方向に進んでいますか?ディレクターはコールバックを実装することを約束しているように見えましたが、Pythonを使用したディレクターの例は見つかりませんでした。

更新:適切なラッピングが生成されています。shared_ptrsを返し、それらを正しく呼び出すことができる他の関数があります。

4

2 に答える 2

0

shared_ptr<T>unknownTは型ではないため、SWIG はラップできません。必要なことは、使用する の各インスタンスに SWIG ラッピングを提供するshared_ptrことです。したがって、たとえばdoCallback()と の両方を使用できるようにしshared_ptr<Foo>たい場合は、次のshared_ptr<Bar>ものが必要になります。

  • のラッパーFoo
  • のラッパーBar
  • shared_ptr<Foo>とのラッパーshared_ptr<Bar>

あなたはそれらを次のようにします:

namespace boost {
    template<class T> class shared_ptr
      {
      public:
          T * operator-> () const;
      };
  }

%template(FooSharedPtr) boost::shared_ptr<Foo>;
%template(BarSharedPtr) boost::shared_ptr<Bar>;
于 2009-10-16T23:31:33.837 に答える
0

私の最初の回答は質問を完全に誤解していたので、もう一度試してみましょう。

あなたの中心的な問題は、Tの定義における自由な型パラメータですdoCallback。あなたの質問で指摘したように、 SWIG オブジェクトを からshared_ptr<T>具体的な値なしで作成する方法はありませんT:shared_ptr<T>は実際にはタイプではありません。

したがって、特殊化する必要があると思います。doCallbackホスト システムが使用する具体的なインスタンス化ごとに、ターゲット タイプのテンプレートの特殊化を提供します。これが完了すると、Python に適した のラッピングを生成し、dataそれを Python 関数に渡すことができます。そのための最も簡単な手法は、おそらく次のとおりです。

swigData = SWIG_NewPointerObj((void*)(data.get()), SWIGType_Whatever, 0);

...ただし、これは、Python 関数がその引数をどこにも保存しない場合にのみ機能します。これは、shared_ptrそれ自体がコピーされないためです。

への参照を保持する必要がある場合はdata、SWIG がラップするために通常使用するメカニズムを使用する必要がありますshared_ptr。特殊なケースのスマート ポインター マジックが行われていない場合は、おそらく次のようになります。

pythonData = new shared_ptr<Whatever>(data);
swigData = SWIG_NewPointerObj(pythonData, SWIGType_shared_ptr_to_Whatever, 1);

いずれにせよ、これで Python に適した SWIG オブジェクトが得られPy_BuildValue()ます。

お役に立てれば。

于 2009-10-20T23:11:22.530 に答える