我正在写一个python包装器到C类,我按照here所解释的那样使用PyMem_Malloc分配内存
cdef class SomeMemory:
cdef double* data
def __cinit__(self, size_t number):
# allocate some memory (uninitialised, may contain arbitrary data)
self.data = <my_data_t*> PyMem_Malloc(number * sizeof(my_data_t))
if not self.data:
raise MemoryError()
然后我使用以下命令导入并在另一个脚本中使用该类:
import SomeMemory
sm = SomeMemory(10)
我现在想访问self.data的元素但我遇到了2个问题
像:
for p in self.data:
print p
我收到一个错误,即self.data不可迭代。
如何访问self.data?我是否需要先将元素转换为my_data_t?
答案 0 :(得分:2)
(根据更新的问题严重编辑)
所以 - 我的理解是self.data
需要声明为public才能从Python访问它:
cdef class SomeMemory:
cdef public double* data
# also make sure you define __dealloc__ to remove the data
但是,这似乎没有强制执行。
但是,您真正的问题是Python不知道如何处理double *
类型的对象。它肯定永远不会被迭代,因为关于何时停止的信息根本就没有存储(所以它总是会结束。
有一系列更好的选择:
代码如下
from cpython cimport array as c_array
from array import array
cdef class SomeMemory:
cdef c_array.array data
def __cinit__(self, size_t number):
self.data = array('d', some initial value goes here)
您将数据存储为numpy数组。这可能稍微复杂一些,但具有相同的优点。我不会举一个例子,但它更容易找到。
您使用Cython的类型内存视图:http://docs.cython.org/src/userguide/memoryviews.html。这样做的好处是它可以让你自己控制内存管理(如果绝对对你很重要)。但是,我并不是100%确定你可以用Python干净地访问它们(懒得测试!)
您将数据包装在您自己的类中,实现__getitem__
和__len__
,以便它可以用作迭代器。这可能是值得的麻烦。
我建议使用第一个选项,除非你有充足的理由选择其中一个。