2016-12-29 8 views
1

私のprojectは、SWIGを使用して、tensorflow.python.pywrap_tensorflowという1つのモジュールに、一連のC++関数と型のラッパーを自動的に作成します。私はPython C APIを使って直接新しい型を定義し、それをそのモジュールに追加したいと思います。 (具体的には、私はmemoryviewとしてネイティブバッファを公開することができるように、Python buffer protocolを実装する新しいタイプを定義したい。)SWIGとPython:手動で作成したクラスをSWIGで生成されたモジュールに追加するにはどうすればよいですか?

私は.iファイルにインライン化することにより、私の新しいタイプのために必要なの構造体を定義することができます:

%{ 

typedef struct { 
    PyObject_HEAD 
    /* Other fields... */ 
} MyType; 

// Define functions for the initializer, destructor, and buffer protocol: 
// * MyType_init 
// * MyType_dealloc 
// * MyType_old_getbuffer (the readbufferproc for Python 2.7) 
// * MyType_segcount (for Python 2.7) 
// * MyType_getbuffer (the Python 2.7/3.x buffer protocol) 

// ... 

static PyBufferProcs MyType_as_buffer = { 
#if PY_VERSION_HEX < 0x03000000 
    (readbufferproc)MyType_old_getbuffer, 
    (writebufferproc)0, 
    (segcountproc)MyType_segcount, 
    (charbufferproc)0, 
#endif 
    (getbufferproc)MyType_getbuffer, 
    (releasebufferproc)0, 
}; 

static PyTypeObject MyType_TypeObject = { 
    /* PyObject header changed in Python 3 */ 
#if PY_VERSION_HEX>=0x03000000 
    PyVarObject_HEAD_INIT(NULL, 0) 
#else 
    PyObject_HEAD_INIT(NULL) 
    0 /* ob_size */, 
#endif 
    "MyType" /* tp_name */, 
    sizeof(MyType) /* tp_basicsize */, 
    0 /* tp_itemsize */, 
    (destructor)MyType_dealloc /* tp_dealloc */, 
    0 /* tp_print */, 
    0 /* tp_getattr */, 
    0 /* tp_setattr */, 
#if PY_VERSION_HEX>=0x03000000 
    0 /* tp_reserved in 3.0.1 */ 
#else 
    0 /* tp_compare */, 
#endif 
    0 /* tp_repr */, 
    0 /* tp_as_number */, 
    0 /* tp_as_sequence */, 
    0 /* tp_as_mapping */, 
    0 /* tp_hash */, 
    0 /* tp_call */, 
    0 /* tp_str */, 
    0 /* tp_getattro */, 
    0 /* tp_setattro */, 
    &MyType_as_buffer /* tp_as_buffer */, 
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER /* tp_flags */, 
    "Python wrapper for MyType." /* tp_doc */, 
    0 /* tp_traverse */, 
    0 /* tp_clear */, 
    0 /* tp_richcompare */, 
    0 /* tp_weaklistoffset */, 
    0 /* tp_iter */, 
    0 /* tp_iternext */, 
    0 /* tp_methods */, 
    0 /* tp_members */, 
    0 /* tp_getset */, 
    0 /* tp_base */, 
    0 /* tp_dict */, 
    0 /* tp_descr_get */, 
    0 /* tp_descr_set */, 
    0 /* tp_dictoffset */, 
    (initproc)MyType_init /* tp_init */, 
}; 

%} 

これを実行した後、私はおそらくモジュールの初期化ブロック(%init %{ ... %})で、PyModule_AddObject()を呼び出すことによって、SWIGが生成したモジュールに型オブジェクトを追加したいです。しかし、tensorflow.python.pywrap_tensorflowモジュールを生成するコードでは、Py_InitModule()(またはPython 3.xではPyModule_Create())から返された値にどのような名前を付けるべきかわかりません。私は%init %{ ... %}ブロックで2番目のモジュールを作成することができましたが、可能であれば自動生成モジュールに追加することをお勧めします。

これらの質問のいずれかに対する答えは、私の問題を解決するだろう:

  • (対応PyObject*ための変数名に拡大するなど、初期化ブロックで生成されたモジュールオブジェクトにアクセスするためのSWIGマクロがあります)?このオブジェクトは、生成されたコードでmというローカル変数に格納されているようですが、すべてのディストリビューションで同じことが保証されているかどうかはわかりません。

  • また、SWIGを使用して達成しようとしていることをもっと慣れ親しんでいる方法はありますか?バッファープロトコルのtypemapsは、documentationのように見えますが、バッファーを受け入れる関数を書くために設計されたようですが、バッファープロトコルを実装するためにはラッパータイプが必要です。

答えて

0

独自のクラスまたは構造体を作成している場合、swigはそのためのpython型を作成します。スロットを追加するだけです。 %feature(python:slot)を試してみてください。この機能により、生成されたPython型のスロットに任意の関数/構造体を追加することができます。また、 '-builtin'オプションを使って.iファイルをビルドすると、不要なプロキシpythonファイルが生成されます。

関連する問題