Я не знаю python и пытаюсь обернуть существующую библиотеку C, которая предоставляет 200 функций инициализации для некоторых объектов и 200 деструкторов с помощью PyCapsule
. Поэтому моя идея - вернуть PyCapsule из упаковщиков функций init и забыть о деструкторах, которые должны вызываться автоматически.
Согласно документации PyCapsule_New()
принимает:
typedef void (*PyCapsule_Destructor)(PyObject *);
, в то время как C -библиотека имеет деструкторы в виде:
int foo(void*);
I ' Я пытаюсь сгенерировать C функцию в .pyx
файле с помощью cdef
, которая сгенерирует C -функцию, которая обернет библиотечный деструктор, скроет возвращаемый тип и передаст указатель, взятый с PyCapsule_GetPointer
, в деструктор , (файл pyx генерируется программно для 200 функций).
После нескольких экспериментов я получаю следующий файл .pyx:
from cpython.ref cimport PyObject
from cpython.pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer
cdef void stateFree( PyObject *capsule ):
cdef:
void * _state
# some code with PyCapsule_GetPointer
def stateInit():
cdef:
void * _state
return PyCapsule_New(_state, "T", stateFree)
И когда я пытаюсь скомпилировать его с помощью Cython Я получаю: Cannot assign type 'void (PyObject *)' to 'PyCapsule_Destructor'
использование PyCapsule_New(_state, "T", &stateFree)
не помогает.
Есть идеи, что не так?
UPD:
Хорошо, думаю, я нашел решение. По крайней мере, это компилируется. Посмотрим, будет ли это работать. Я выделю места, которые, как мне кажется, я допустил:
из cpython .ref cimport PyObject
из cpython .pycapsule cimport PyCapsule_New, PyCapsule_IsValid, PyCapsule_GetPointer , PyCapsule_Destructor
cpdef void stateFree ( объект капсула):
cdef:
void * _state
_state = PyCapsule_GetPointer ( капсула, "T")
print ('уничтожено')
def stateInit ():
cdef:
int _state = 1
print ("initialized")
return PyCapsule_New (_state, "T", stateFree)