У меня есть файл pxd, который объявляет некоторые типы с помощью ctypedef, а некоторые функции с помощью cdef.Чтобы вызвать одну конкретную функцию, мне нужно продублировать typedefs в моем файле pyx.
Если я переместу cdef функции в файл pyx, он не сможет скомпилировать с «Cannot преобразовать state_t *» в объект Python».Ошибка относится к этой строке кода
retval = c_explanation.table_of_states_is_bad(<state_t*>test_array, b)
Параметр test_array создается локально с помощью malloc, поэтому вообще не является объектом python.
Если удалить typedefs из файла pyx и импортироватьих и cdef из файла pxd с from .. import *, я получаю ту же ошибку компиляции.
Единственный способ заставить этот простой кусочек кода работать - это довольно неловкое дублированиеtypedefs в файлах pyx и pxd.
Есть мысли о том, что здесь происходит и как решить эту проблему?
Полный код вставлен ниже
pyx file
from libc.stdlib cimport malloc, free
cimport c_explanation
cdef extern from "explanation.h":
ctypedef int state_id;
ctypedef struct event_t:
pass
ctypedef void (*event_handler)(event_t event)
ctypedef struct state_t:
state_id id
event_handler handle
char *name
ctypedef enum bool:
pass
def table_of_states_is_bad(a, b):
cdef state_t *test_array
cdef bool retval
test_array = <state_t*>malloc(len(a) * sizeof(state_t))
if not test_array:
raise MemoryError()
try:
for i, s in enumerate(a):
test_array[i].id = s[0]
retval = c_explanation.table_of_states_is_bad(test_array, b)
return retval
finally:
free(test_array)
файл pxd
cdef extern from "explanation.h":
cdef int mock_get_temp(int)
ctypedef enum bool:
pass
ctypedef struct event_t:
pass
ctypedef void (*event_handler)(event_t event);
ctypedef int state_id;
ctypedef struct state_t:
state_id id
event_handler handle
char *name
cdef bool table_of_states_is_bad(state_t table[], size_t size)
наконец файл h
int mock_get_temp(int);
typedef int event_id;
/* an event */
typedef struct {
event_id id; /* numeric id */
void *data; /* points to anything */
char *name; /* points to string for debug or log */
} event_t;
typedef void (*event_handler)(event_t event);
typedef enum { false, true } bool;
typedef int state_id;
/* a state */
typedef struct {
state_id id; /* numeric id */
event_handler handle; /* points to handler */
char *name; /* points to string for debug or log */
} state_t;
bool table_of_states_is_bad(state_t table[], size_t size);