Python使用CFFI調用C動態庫

初始化

from cffi import FFI
ffi = FFI()

| 版權聲明:itisyang,未經博主允許不得轉載。https://blog.csdn.net/itisyang/article/details/54426631

加載C動態庫

lib_IOTCAPIs = ffi.dlopen("./tutk_lib/libIOTCAPIs.so")

這種方法加載動態庫若是多個庫之間有交錯調用,則會報錯,若多個庫之間存在交錯調用,可使用下面的方法

lib_IOTCAPIs = ffi.dlopen("./tutk_lib/libIOTCAPIs.so", flags=256)  # RTLD_GLOBAL = 256

此處dlopen使用方法同標準C中void *dlopen(const char *filename, int flags);相似

加載並調用C動態庫函數

ffi.cdef("int IOTC_Initialize2(unsigned short nUDPPort);")
lib_IOTCAPIs.IOTC_Initialize2(0)  # 調用

加載並調用C結構體

ffi.cdef("""
typedef struct{
    unsigned int channel;
    unsigned char reserved[];
}SMsgAVIoctrlAVStream;
""")
buf = ffi.new('SMsgAVIoctrlAVStream *', [ChannelID, 4]) 
buf1 = ffi.new('SMsgAVIoctrlAVStream ', [ChannelID, “1234”])  # 調用
buf2 = ffi.new('SMsgAVIoctrlAVStream[]', 10)
buf3 = ffi.new('SMsgAVIoctrlAVStream[10]')

分別調用了結構體指針、結構體、結構體數組,buf2和buf3效果是相同的

加載並調用C基本類型

基本類型包括 int、 char、unsigned int、unsigned char、 char[]、int[]、int*、char **…

x = ffi.new("char[]", "hello")
print len(x),x[0],ffi.string(x)

輸出 6 h hello

array = ffi.new("int[]", [1, 2, 3, 4])

相當於int array[] = { 1, 2, 3, 4 };

x = ffi.new("int *")
x[0] = 42
print x[0]

輸出 42

調用標準C函數

ffi.cdef("""
int printf(const char *format, ...);   // copy-pasted from the man page
""")
C = ffi.dlopen(None)                     # 導入全部C函數命名空間
arg = ffi.new("char[]", "world")         # 相當於 char arg[] = "world";
C.printf("hi there, %s.\n", arg)         # 調用 printf

輸出 hi there, world.

轉換指針類型

frame_info = ffi.new('PPSDEV_MEDIA_HEADER *')
frame_p = ffi.cast("char *", frame)

將 PPSDEV_MEDIA_HEADER* 指針轉換爲 char* 指針

加載C頭文件

ffi.cdef("""
#include <library.h>
""")

若需要使用的庫函數過多,一個一個加載麻煩,可採用這種方法一次性加載
注意頭文件中的函數接口需要寫成標準的方式,一些爲跨平臺寫的東西有可能報錯,跨平臺性能最好是在動態庫中包含,在頭文件剔除

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章