python调用c 接口_python调用C接口
5、結構體定義
我們用 fields = [(‘name1’,type1),(‘name2’,type2)]來表示結構體的成員
字節對齊 C結構體中經常會出現按照指定的字節進行對齊結構體,用pack來指定對齊的字節數,數組的定義直接用 *num 表示個數
C
#pragma pack(1)
structMyStruct
{inta;doubleb;char c[32];
};#pragma pack()
python
classMyStruct(Structure):
_fields_=[
('a',c_int),
('b',c_double),
('c',c_char*32),
]
_pack_= 1
位域
C
structMyStruct1
{int a : 16;int b : 16;
};
python
classMyStruct1(Structure):
_fields_=[
('a',c_int,16),
('b', c_int, 16),
]
結構體的嵌套
c
structMyStruct2
{inta;
MyStruct S[4];
};
classMyStruct2(Structure):
_fields_=[
('a',c_int),
('struct',MyStruct*4)
]
傳遞結構體,與之前傳遞參數一樣,指針類型用byref或者pointer
c
DLL1_API int fnDLL5(MyStruct &s)
{
printf("mystruct:\na:%d\nb:%f\nc:%s\n", s.a, s.b, s.c);return 1;
}
python
mystruct =MyStruct()
mystruct.a= 1mystruct.b= 1.0mystruct.c= 'helloworld'.encode('gbk')
dll.fnDLL5(byref(mystruct))
dll.fnDLL5(pointer(mystruct))
返回結構體,與之前相同,需要指定返回的類型
c
DLL1_API MyStruct fnDLL6()
{
MyStruct*tem = newMyStruct;
tem->a = 10;
tem->b = 20;
sprintf(tem->c, "hello");return *tem;
}
python
dll.fnDLL6.restype =MyStruct
res=dll.fnDLL6()print(res)print('mystruct:', res.a, res.b, res.c)del res
高階數組的定義
int my_array[10][10];
#先定義一個數組類型
type_int_array_10 = c_int * 10
#定義數組的數組(即二維數組)
type_int_array_10_10 = type_int_array_10 * 10
#創建二維數組對象
my_array =type_int_array_10_10()#使用二維數組
my_array[1][2] = 3
字節流與結構體的相互轉換
#pack
print(string_at(addressof(mystruct),sizeof(mystruct)))#unpack
buf =bytes(sizeof(MyStruct))assertlen(buf)
buf=create_string_buffer(sizeof(MyStruct))
res=cast(pointer(buf),POINTER(MyStruct)).contentsprint(res,type(res))print('mystruct:',res.a,res.b,res.c)
defPack(ctype_instance):returnstring_at(addressof(ctype_instance),sizeof(ctype_instance))defUnPack(ctype,buf):assert sizeof(ctype) ==len(buf)
cstring=create_string_buffer(buf)return cast(pointer(cstring),POINTER(ctype)).contents
回調函數
先用CFUNCTYPE 定義回調函數類型,參數的第一個參數為返回值類型
后面的參數為回調函數傳遞的參數類型,然后定義python中的函數,
C
typedef int (*callbakc) (int a, intb);
DLL1_APIvoid fnDLL7(int a, intb, callbakc func)
{int n =func(a, b);
printf("c++ callback %d\n", n);
}
python
CMPFUNC =CFUNCTYPE(c_int,c_int,c_int)
cmp_func=CMPFUNC(callFunc)
dll.fnDLL7(1,2,cmp_func)
這里有個地方特別注意,如果回調函數中有void* ,char等類型,在python中定義回調函數的時候如果定義為 c_void_p ,c_char_p,實際返回的數據為int,bytes
這時候其實python內部已經把參數的值拿出來了,而我們需要的是char地址的內容,常用的比如傳遞某一串字節流,我們需要傳遞出字節流的長度和首地址的指針,如果直接使用參數,c_void_p拿到的是一個int類型,而c_char_p拿到的是截止到最后一個'\0'的字節,最終我們在python中用string_at 來拿到實際的字節流
c回調
typedef void (*callbakc) (void * buf, int &buf_size);
python中的定義
string = string_at(buf,size.value)
defcallback(buf,size):
string=string_at(buf,size.value)
CALLBACKFUNC=CFUNCTYPE(None,c_void_p,c_int)
call= CALLBACKFUNC(callback)
總結
以上是生活随笔為你收集整理的python调用c 接口_python调用C接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python excel操作xlrd_p
- 下一篇: shell mysql版本_mysql版