2016-12-29 51 views
1

我的project使用SWIG在一個名爲tensorflow.python.pywrap_tensorflow的模塊中自動爲一組C++函數和類型創建包裝。我想直接使用Python C API定義一個新類型,並將其添加到該模塊中。 (我特別想定義一個新類型,實現了Python buffer protocol,讓我可以公開一個本地緩存爲memoryviewSWIG和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 */, 
}; 

%} 

這樣做後,我想類型對象添加到SWIG生成模塊,通過調用PyModule_AddObject(),想必在模塊初始化塊(%init %{ ... %})。但是,我不知道在創建tensorflow.python.pywrap_tensorflow模塊的生成代碼中爲Py_InitModule()(或Python18.x中的PyModule_Create())返回的值給出了什麼名稱。我已經能夠在%init %{ ... %}塊中創建第二個模塊,但如果可能的話,我寧願將其添加到自動生成的模塊中。

的回答要麼這些問題會解決我的問題:

  • 是否有在初始化塊存取生成模塊對象痛飲宏(例如,通過擴大在變量名稱爲相應PyObject* )?這個對象似乎被存儲在我生成的代碼中的一個名爲m的局部變量中,但我不知道這是否保證在所有發行版中都是相同的。

  • 還是有一種更習慣的方法來做我想用SWIG實現的目標?從他們的documentation似乎緩衝區協議類型映射似乎被設計爲編寫接受緩衝區作爲參數的函數,而我希望我的包裝類型來實現緩衝區協議。

回答

0

如果您正在編寫自己的類或結構,swig將爲它創建一個python類型,並且您所要做的就是添加插槽。嘗試%功能(python:slot)。該功能可以讓你添加任意的函數/結構到生成的python類型的插槽。同時使用'-builtin'選項構建你的.i文件,釋放不必要的代理python文件。

相關問題