python與C互動中傳入與讀取記憶體空間
阿新 • • 發佈:2018-11-26
使用用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中進行測試的