使用用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中进行测试的