1. 程式人生 > >python與C互動中傳入與讀取記憶體空間

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中進行測試的