python与C交互中传入与读取内存空间

使用用python调用c代码中,从外部传入一个固定大小的内存空间,这段内存需要是可写的

首先看下c中的函数

typedef struct ModelData
{
    unsigned int    model_len;          //数据长度
    char*           model_data;
}Model_Data;

int SessionBegin(INST nst, Model_Data* model_data);

 

首先再python中定义对应的结构体

class ISV_ModelData(Structure):
    _fields_ = [
        ('model_len', c_uint),
        ('model_data', c_void_p)
    ]

虽然c中的结构体是char *,这里并没有定义成c_char_p,因为这段内存需要支持写入,并且便于后面读取。

    model_res = Model_Data()
    model_len = 1024 * 1024
    raw_memory = bytearray(model_len )
    ctypes_raw_type = (c_char * model_len )
    ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory)
    # 通过ctypes对象的addressof获得内存指针的值
    raw_address = addressof(ctypes_raw_memory)
    model_res.model_data = c_void_p(raw_address)
    model_res.model_len = model_len 

  这样我们就有了一段1024*1024的空白的内存空间

ret = so.SessionBegin(inst, byref(model_res))

  

同样也可以传入一段有内容的空间

    model_res = Model_Data()
    raw_model_data = open('xx', 'rb').read()
    raw_memory = bytearray(raw_model_data)
    ctypes_raw_type = (c_char * len(raw_model_data))
    ctypes_raw_memory = ctypes_raw_type.from_buffer(raw_memory)
    # 通过ctypes对象的addressof获得内存指针的值
    raw_address = addressof(ctypes_raw_memory)
    model_res.model_data = c_void_p(raw_address)
    model_res.model_len = len(raw_model_data)

  

当c中处理完成后,如何读取里面的内容,这里如果c_char_p的话就不好处理了

model_out_value = (c_int8 * model_res.model_len).from_address(model_res.model_data)
model_out_value_str = struct.pack("%sb" % model_res.model_len, *model_out_value)

以上都是在python2中进行测试的

原文地址:https://www.cnblogs.com/lilinwei340/p/10018272.html