gpt4 book ai didi

python - Cython 从函数返回 malloced 指针

转载 作者:太空宇宙 更新时间:2023-11-03 14:46:21 27 4
gpt4 key购买 nike

我是 Cython 的新手,所以这可能相当微不足道,但我无法在任何地方找到答案。

我已经定义了一个结构类型,我想编写一个函数来正确初始化所有字段并返回指向新结构的指针。

from cpython.mem import PyMem_Malloc


ctypedef struct cell_t:
DTYPE_t[2] min_bounds
DTYPE_t[2] max_bounds
DTYPE_t size

bint is_leaf
cell_t * children[4]

DTYPE_t[2] center_of_mass
UINT32_t count


cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds):
cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t)) # <- Fails here
if not cell:
MemoryError()

cell.min_bounds[:] = min_bounds
cell.max_bounds[:] = max_bounds
cell.size = min_bounds[0] - max_bounds[0]
cell.is_leaf = True
cell.center_of_mass[:] = [0, 0]
cell.count = 0

return cell

但是,当我尝试编译它时,在编译过程中出现以下两个错误:

cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds):
cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t))
^
Casting temporary Python object to non-numeric non-Python type
------------------------------------------------------------

cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds):
cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t))
^
Storing unsafe C derivative of temporary Python reference
------------------------------------------------------------

现在,我查看了所有内容,据我所知,cell 实际上存储在一个临时变量中,该变量在函数结束时被释放。

如有任何帮助,我们将不胜感激。

最佳答案

cell.min_bounds = min_bounds

这并不像您想象的那样(尽管我不是 100% 确定它的作用)。您需要逐个元素地复制数组:

cell.min_bounds[0] = min_bounds[0]
cell.min_bounds[1] = min_bounds[1]

对于 max_bounds 也是如此。

我怀疑给您错误消息的行是:

cell.center_of_mass = [0, 0]

这是试图将 Python 列表分配给 C 数组(记住数组和指针在 C 中有些可互换),这没有多大意义。再一次,你会做

cell.center_of_mass[0] = 0
cell.center_of_mass[1] = 0

所有这些在很大程度上与 C 行为一致,即没有运算符将整个数组相互复制,您需要逐个元素复制。


编辑:

但这不是您的直接问题。您还没有声明 PyMem_Malloc 所以它被假定为一个 Python 函数。你应该做的

from cpython.mem cimport PyMem_Malloc

确保它是cimported,而不是imported


编辑2:

以下编译对我来说很好:

from cpython.mem cimport PyMem_Malloc

ctypedef double DTYPE_t

ctypedef struct cell_t:
DTYPE_t[2] min_bounds
DTYPE_t[2] max_bounds


cdef cell_t * make_cell(DTYPE_t[2] min_bounds, DTYPE_t[2] max_bounds) except NULL:
cdef cell_t * cell = <cell_t *>PyMem_Malloc(sizeof(cell_t))
if not cell:
raise MemoryError()
return cell

我已经减少了一些 cell_t(只是为了避免必须声明 UINT32_t)。我还为 cdef 函数提供了一个 except NULL 以允许它在需要时发出错误信号,并在 MemoryError 之前添加了一个 raise ()。我不认为这些更改中的任何一个与您的错误直接相关。

关于python - Cython 从函数返回 malloced 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48995495/

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