gpt4 book ai didi

python - SWIG 和 Python : How can I add a manually-created class to a SWIG-generated module?

转载 作者:行者123 更新时间:2023-11-28 19:10:15 26 4
gpt4 key购买 nike

我的 project使用 SWIG在名为 tensorflow.python.pywrap_tensorflow 的单个模块中自动为一组 C++ 函数和类型创建包装器。我想直接使用 Python C API 定义一个新类型,并将其添加到该模块。 (特别是,我想定义一个实现 Python buffer protocol 的新类型,这样我就可以将 native 缓冲区公开为 memoryview。)

我可以通过在 .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 */,
};

%}

完成此操作后,我想通过调用 PyModule_AddObject() 将类型对象添加到 SWIG 生成的模块中,大概在模块初始化 block 中 (%init %{ ... %})。但是,我不知道给从 Py_InitModule() 返回的值起什么名字。 (或 Python 3.x 中的 PyModule_Create())在创建 tensorflow.python.pywrap_tensorflow 模块的生成代码中。我已经能够在 %init %{ ... %} block 中创建第二个模块,但如果可能,我更愿意将其添加到自动生成的模块中。

以下任一问题的答案都可以解决我的问题:

  • 是否有用于访问初始化 block 中生成的模块对象的 SWIG 宏(例如,通过扩展为相应 PyObject* 的变量名)?在我生成的代码中,这个对象似乎存储在一个名为 m 的局部变量中,但我不知道这是否保证在所有发行版中都相同。

  • 或者是否有更惯用的方法来完成我使用 SWIG 尝试实现的目标?缓冲区协议(protocol)类型映射似乎来自他们的 documentation似乎是为编写接受缓冲区作为参数的函数而设计的,而我希望我的包装器类型能够实现缓冲区协议(protocol)。

最佳答案

只是为了让 Jacky 的回答更明确——你可能想做类似的事情:

%{
static *PyBuffer mycoolbuffer_function(PyObject* self) {
// get the C data for self
// build your buffer
}
%}

%feature("python:tp_as_buffer") MyTypeThatWillBeWrapped "&mycoolbuffer_function";

这有点未经测试,我是从我用迭代器做的一些工作中类推的。它当然需要 -builtin 选项。

关于python - SWIG 和 Python : How can I add a manually-created class to a SWIG-generated module?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41387832/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com