2016-12-29 2 views
1

My project использует SWIG для автоматического создания оберток для набора функций и типов C++ в одном модуле, который называется tensorflow.python.pywrap_tensorflow. Я хочу напрямую определить новый тип, используя API Python C, и добавить его в этот модуль. (В частности, я хочу, чтобы определить новый тип, который реализует Python buffer protocol, так что я могу выставить родной буфер как memoryview.)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 */, 
}; 

%} 

После этого, я хочу, чтобы добавить объект типа к модулю SWIG сгенерированных путем вызова PyModule_AddObject(), предположительно, в блоке инициализации модуля (%init %{ ... %}). Однако я не знаю, какое имя следует указать для значения, возвращаемого с Py_InitModule() (или PyModule_Create() в Python 3.x) в сгенерированном коде, который создает модуль tensorflow.python.pywrap_tensorflow. Мне удалось создать второй модуль в блоке %init %{ ... %}, но я предпочел бы добавить его в автоматически сгенерированный модуль, если это возможно.

Ответ на любой из этих вопросов позволит решить мою проблему:

  • Есть ли SWIG макрос для доступа сгенерированного объекта модуля в блоке инициализации (например, путем расширения к имени переменному для соответствующего PyObject*)? Кажется, что этот объект хранится в локальной переменной с именем m в моем сгенерированном коде, но я не знаю, гарантировано ли это во всех дистрибутивах.

  • Или есть более идиоматический способ сделать то, что я пытаюсь достичь с помощью SWIG? Буквенные протоколы typemaps выглядят с их documentation, казалось, предназначены для написания функций, которые принимают буферы в качестве аргументов, тогда как я хочу, чтобы мой тип-оболочка реализовал буферный протокол.

ответ

0

Если вы пишете собственный класс или структуру, swig построит для него тип python, и все, что вам нужно сделать, это добавить слоты. Попробуйте функцию% (python: slot). Эта функция позволяет добавлять произвольные функции/структуры в сгенерированный слот типа python. Также создайте свой .i-файл, используя опцию -builtin, испустите ненужный файл-пионер-прокси.

Смежные вопросы