python調用c庫之cffi

python使用cffi模塊調用c函數
一、cffi簡介
  Cffi是python調用c函數的接口。幾乎所有c和pythond的交互都是基於類似於c的聲明一樣,因此可以直接複製粘貼c的頭文件或者文檔使用。
  Cffi接口遵循如下的原則:
  1、目標是在不需要了解第三方語言(cython、swig、ctypes)的基礎上在python中調用c庫函數;cffi的設計只需要用戶瞭解c和python,最大限度的減少用戶學習額外的api;
  2、保存原有python的邏輯不需要寫太多的c代碼;從python代碼頭部的cdef聲明中調用c編譯器去驗證和連接到c數據結構及函數;
  3、越來越完善;到現在爲止c99並不是全部支持,但是c89應該全部支持了,包含一些宏定義;
  4、嘗試去支持cpython和pypy;
  5、此項目不是在python中嵌入可執行c代碼,而是關於如何在python中調用已存在的c庫函數;
  6、不支持c++
  
二、相關api的使用
參考官方文檔:
https://cffi.readthedocs.io/en/release-1.12/ref.html

三、加載並調用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

轉換指針類型
stu = ffi.new(‘struct stu*’)
stu_ptr = ffi.cast(“char *”, stu)

三、使用筆記

import cffi
import setproctitle

#實例化ffi
ffi=cffi.FFI()

#此處可以寫宏定義、結構體、函數聲明、全局變量等;
ffi.cdef("""
		#define MAX_CLASS 10
		#define MAX_COUNT 20
		typef struct {
			int age;
			char sex;
			float high;
		}student;
		int count_student();#函數聲明
		int get_specical_stu(void *()(int id))
			""")

#加載so庫(會自動搜索系統路徑),如果so庫之間有相互依賴關係,則使用ffi.RTLD_LAZY|ffi.RTLD_GLOBAL模式加載
liba=ffi.dlopen("liba.so",ffi.RTLD_LAZY|ffi.RTLD_GLOBAL)
libb=ffi.dlopen("libb.so",ffi.RTLD_GLOBAL)

#函數調用
liba.count_student()

#將python函數作爲回調函數註冊到c函數中
c_handle_test=ffi.new_handle(python_func) #結合ffi.from_handle使用
libb.get_special(c_handle_test)

#創建c類型的對象並初始化
c_stu_struct=ffi.new("student",[25,1,176])

#進程起別名
setproctitle.setproctitle("test_name")


參考文章:
官方文檔:https://cffi.readthedocs.io/en/release-1.12/ref.html
使用實例:http://wiki.jikexueyuan.com/project/openresty/lua/FFI.html
使用實例:https://blog.csdn.net/itisyang/article/details/54426631

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