几天来我一直在尝试各种方法,但似乎缺少一些关键的成分。我试图创建一个C结构数组,并从Python字典中填充这些结构。我想在类定义或一些全局函数中捕获它,因为我将在代码中的多个位置使用它。你知道吗
根据请求,我已将代码解构为其最低版本,并将其全部放在一个文件中:
FOO_BOOL = 1
FOO_BYTE = 2
FOO_STRING = 3
cdef union Data:
bint flag
int byte
char *string
ctypedef struct bar_t:
char name[512]
int type
Data data
cdef class BarArray:
cdef bar_t *array;
cdef size_t nbars;
def __cinit__(self, number):
self.array = <bar_t*>malloc(number * sizeof(bar_t))
if not self.array:
raise MemoryError()
self.nbars = number
def load(self, keyvals:dict):
kvkeys = list(keyvals.keys())
if len(kvkeys) > <int>self.ninfo:
# this should never happen except in development
# so raise an error to let them know
raise IndexError()
n = 0
for key in kvkeys:
if keyvals[key][1] == 'bool':
self.array[n].type = FOO_BOOL
self.array[n].data.flag = keyvals[key][0]
elif keyvals[key][1] == 'byte':
self.array[n].type = FOO_BYTE
self.array[n].data.byte = keyvals[key][0]
elif keyvals[key][1] == 'string':
self.array[n].type = FOO_STRING
if isinstance(keyvals[key][0], str):
pykey = keyvals[key][0].encode('ascii')
else:
pykey = keyvals[key][0]
try:
self.array[n].data.string = strdup(pykey)
except:
raise ValueError("String value declared but non-string provided")
else:
raise TypeError("UNRECOGNIZED VALUE TYPE")
n += 1
@property
def array(self):
return self.array
@property
def nbars(self):
return self.nbars
cdef class FooClass():
cdef bar_t *array
cdef size_t sz
def __cinit__(self, sz):
self.bar = BarArray(sz)
def loadarray(self, keyvals:dict):
self.bar.load(keyvals)
self.array = <bar_t*>self.bar.array
while n < self.sz:
print("INFO [", n, "]: ", self.array[n].name, self.array[n].type)
n += 1
尝试编译时,出现以下错误:
warning: foobar.pyx:28:16: cdef variable 'array' declared after it is used
Error compiling Cython file:
------------------------------------------------------------
...
raise TypeError("UNRECOGNIZED VALUE TYPE")
n += 1
@property
def array(self):
return self.array
^
------------------------------------------------------------
foobar.pyx:67:19: Cannot convert 'bar_t *' to Python object
我在一个地方读到,你必须把这个返回值转换成,但这也会产生一个错误。我最终成功地找到了一种克服编译错误的方法,但是返回的数组包含垃圾。你知道吗
如有任何建议,将不胜感激。你知道吗
将指针发送回Python实际上是没有意义的(因此您看到了错误)。我认为您要做的是定义Python访问器函数
__setitem__
和__getitem__
:请注意,您需要注意内存管理。因为您不能依赖于指向Python字符串中保存的数据的指针,所以您需要自己为它们分配内存。这还意味着您需要确保在类被破坏或替换数组元素时释放它。我跳过了编写这段代码,因为它在很大程度上取决于您使用的C库。你知道吗
相关问题 更多 >
编程相关推荐