将指向数组值的指针从Cython传递给C.

时间:2018-04-03 15:35:40

标签: python c pointers cython ctypes

我在C中有一个看起来像这样的结构:

typedef struct {
    uint32_t id;
    uint8_t *buf; // pointer to message data
} msg_t;

和一些接收指向这种结构的指针并修改它的函数。

void recv_msg( msg_t *msg ) {
    // Stuff happens to message here
    return;
}

对于细胞,我尝试过这样的事情:

from cytpes import CDLL, Structure, POINTER, c_ubyte, c_uint32

class Msg(Structure):
    _fields_ = [("id", c_uint32), ("buf", POINTER(c_ubyte * 10))]

lib = CDLL("this_example.so")
get_msg = lib.recv_msg
get_msg.argtypes = [POINTER(Msg)]
get_msg.restype = None

sample_data_array = POINTER(c_ubyte * 10)()
data = sample_data_array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
sample_msg = Msg(1, data)
get_msg(sample_msg)
print sample_msg.id, sample_msg.buf[0]  # Should change data

我收到了一个TypeError('预期的LP_c_ubyte_Array_10实例,得到了列表')

我也尝试过使用Cython的类似方法:

from libc.stdint cimport uint8_t, uint32_t

cdef extern from "this_example.h":
    ctypedef struct msg_t:
        uint32_t id;
        uint8_t *buf;

    void get_msg (msg_t *)

def recv_msg():
    # How I would do this I don't know
    print msg.id, msg.buf[0]

我还应该补充一点,我不想使用numpy(但如果必须,我会不情愿)。此外,数据数组的长度可以变化,但我在msg结构中也有一个长度变量,因此我可以将其初始化为正确的发送长度,并将其设置为默认值和接收的最大长度。

任何线索?谢谢!

1 个答案:

答案 0 :(得分:0)

我愿意接受其他答案,但是现在我想我会发布我的解决方案,希望它可以帮助其他人。

我使用细胞而不是Cython解决了它。 我真的很想看到一个Cython解决方案

from ctypes import CDLL, Structure, POINTER, c_uint8, c_uint32, byref

class Msg(Structure):
    _fields_ = [("id", c_uint32), ("buf", POINTER(c_uint8))]

lib = CDLL('this_example.so')
get_msg = lib.recv_msg
get_msg.argtypes = [POINTER(Msg)]
get_msg.restype = None

data = (c_uint8 * 8)()
sample_msg = Msg(1, data)
get_msg(byref(sample_msg))
print sample_msg.id, sample_msg.buf[0]  # Should see changed data