私の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のように見えますが、バッファーを受け入れる関数を書くために設計されたようですが、バッファープロトコルを実装するためにはラッパータイプが必要です。