目前我正在尝试使用类型化内存视图来获取结构。 E.g。
ctypedef struct node:
unsigned int[:] inds
如果inds不是一个记忆视图,就我所见,它可以完美无缺地工作。但是,使用memoryview并使用类似
的内容def testFunction():
cdef node testNode
testNode.inds = numpy.ones(3,dtype=numpy.uint32)
我收到了分段错误。有什么明显的东西我可以忽略或者输入的内存视图在结构中不起作用吗?
编辑:
所以我稍微重写了一下这个例子(由于larsman的问题),希望能够稍微澄清一下这个问题:
def testFunction():
cdef node testNode
cdef unsigned int[:] tempInds
tempInds = numpy.ones(3,dtype=numpy.uintc)
testNode.inds = tempInds
只有最后一行产生段错误。我不知道如何更详细地检查问题。对我来说,它目前只是看起来结构不能处理类型化的内存视图...但希望我错过了一些东西。
我正在使用Cython 0.20(现在刚刚更新,之前0.19给出了同样的错误)。将Numpy更新为1.8.0。
编辑2:
如果有类似问题的人在将来读到这个:我现在搜索了很多,但无法让它工作。除了内存视图以外,其他一切都在工作,我猜它不是(轻松)可能的。 我打算使用内存视图,因为方便切片多维数组,但显然它们不适用于结构。现在我在结构中保存一个C指针,如果我需要切片,则将它们转换为内存视图......必须非常小心才能正确访问数组,但在我的情况下它似乎可以正常工作。如果从现在起几周内该线程中没有解决答案,我可能正在为Cython做一个功能请求。
答案 0 :(得分:1)
问题来自未初始化的内存,因为Cython缺少原始cdefed结构的构造函数。当testNode.inds = tempInds赋值时,Cython尝试释放testNode.inds,它甚至没有正确初始化并取消引用随机指针。
这确实是Cython中的错误(请提交!)并且目前还没有解决方案(据我所知),但这是一个有效的丑陋黑客。
from libc.string cimport memset
ctypedef struct node:
int dummy_hack
unsigned int[:] inds
def testFunction():
cdef node testNode
cdef unsigned int[:] tempInds
tempInds = numpy.ones(3,dtype=numpy.uintc)
# zero init memory to avoid deref garbage
memset(&testNode.dummy_hack, 0, sizeof(void*)*4)
testNode.inds = tempInds
FYI。 C ++中的实际内存视图对象如下所示(在Cython 21.2上):
MemoryView object is
__Pyx_memviewslice struct typedef struct {
struct __pyx_memoryview_obj *memview;
char *data;
Py_ssize_t shape[8];
Py_ssize_t strides[8];
Py_ssize_t suboffsets[8];
};