使用ctypes

时间:2016-02-16 16:40:13

标签: arrays pointers struct ctypes

根据我从参考文献中学到的内容并阅读official ctypes tutorial。我可以在Python中重新创建和引用C / C ++结构的元素。 所以我有这个结构:

typedef struct {
    PyObject_HEAD
    BVHTree *tree;
    float epsilon;
    float (*coords)[3];
    unsigned int (*tris)[3];
    unsigned int coords_len, tris_len;
    int *orig_index;
    float (*orig_normal)[3];
} PyBVHTree;

我试图这样做ctypes:

import ctypes
class PyBVHTree(ctypes.Structure):
    _pack_ = 8
    _fields_ = [
    ("ob_base",      ctypes.py_object), #PyObject_HEAD
    ("tree",         ctypes.c_void_p),
    ("epsilon",      ctypes.c_float),
    ("coords",       ctypes.POINTER(ctypes.c_float * 3)),
    ("tris",         ctypes.POINTER(ctypes.c_uint * 3)),
    ("coords_len",   ctypes.c_uint),
    ("tris_len",     ctypes.c_uint),
    ("orig_index",   ctypes.POINTER(ctypes.c_int)),
    ("orig_normal",  ctypes.POINTER(ctypes.c_float * 3)),
    ]

我用这种方式引用python对象:

c_tree = PyBVHTree.from_address(id(tree))

" epsilon"我可以毫无问题地得到,但当我试图获得" coords" ...... CRASH !!!

我想我没有以正确的方式引用数组的指针。 如何在ctypes中引用带有3个元素的数组指针?

1 个答案:

答案 0 :(得分:1)

正如@eryksun所解释的那样,我的错误在于我将指针引用为PyObject_HEAD。 正确的方法:

import ctypes

class PyObject_HEAD(ctypes.Structure):
    _fields_ = [
    ("ob_refcnt",    ctypes.c_ssize_t),
    ("ob_type",      ctypes.c_void_p),
    ]

class PyBVHTree(ctypes.Structure):
    #_pack_ = 8
    _fields_ = [
    ("ob_base",      PyObject_HEAD),
    ("tree",         ctypes.c_void_p),
    ("epsilon",      ctypes.c_float),
    ("coords",       ctypes.POINTER(ctypes.c_float * 3)),
    ("tris",         ctypes.POINTER(ctypes.c_uint * 3)),
    ("coords_len",   ctypes.c_uint),
    ("tris_len",     ctypes.c_uint),
    ("orig_index",   ctypes.POINTER(ctypes.c_int)),
    ("orig_normal",  ctypes.POINTER(ctypes.c_float * 3)),
    ]