目錄
簡要說明
開發環境
封裝資料結構 陣列
結構體 指標
列舉 函式傳遞結構體引數 備註
ctypes
是python的外部函式庫。它提供c相容的資料型別,並允許在dll或共享庫中呼叫函式,它可以用於在純python中包裝這些庫。cdll 載入使用標準cdecl
呼叫約定匯出函式的庫,而windll庫使用stdcall
呼叫約定呼叫函式。呼叫形式如下:
from ctypes import *作業系統:window7clib = windll.loadlibrary("c:\\users\\ad\\desktop\\python_test\\python_visa_test\\***.dll")
python版本:3.4.4
對於c語言中經常用到的陣列、結構體、指標、列舉等型別,ctypes模組都提供了封裝。ctypes定義了許多原始的c相容資料型別,如下:
#char型的一位陣列,長度為8ctypes中將結構體封裝成類,需要繼承structure,在_fields_中定義成員,如下:x = c_char * 8
#int型的一位陣列,長度為8
y= c_int * 8
#int型的二維陣列(等同於c語言: int z[8][256])
z = y*256
class deviceinfo(structure):通過pointer在ctypes型別上呼叫函式 來建立指標例項:x= c_char * 8
y = c_char * 8
z= c_char * 8
_fields_ = [("x1",x* 256), #二維陣列
("y1",y* 256),
("z1",z* 256),
("n",c_int * 8),
("m",c_int),
("a",c_int),
("b",c_char * 8 )]
指標例項有乙個from ctypes import *i = c_int(42)
pi = pointer(i)
contents
屬性,它返回指標指向的i
物件,上面的物件:
注意,>>> pi.contentsc_long(42)
>>>
ctypes
沒有oor(原始物件返回),每次檢索屬性時它都會構造乙個新的等效物件 :
將另乙個>>> pi.contents is ifalse
>>> pi.contents is pi.contents
false
>>>
c_int
例項分配給指標的contents屬性會導致指標指向儲存它的記憶體位置:
該>>> i = c_int(99)>>> pi.contents = i
>>> pi.contents
c_long(99)
>>>
pointer()
函式不僅僅是建立指標例項,還必須首先建立指標型別。這是通過pointer()
接受任何ctypes
型別的函式完成的 ,並返回乙個新型別 :
呼叫不帶引數的指標型別會建立乙個>>> pi = pointer(c_int)>>> pi
>>> pi(42)
traceback (most recent call last):
file "", line 1, in typeerror: expected c_long instead of int
>>> pi(c_int(42))
>>>
null
指標。null
指標有乙個false
布林值:
>>> null_ptr = pointer(c_int)()>>> print(bool(null_ptr))
false
>>>
ctypes
檢查null
何時解除引用指標(但解除引用無效的非null
指標會使python崩潰):
列舉需要繼承enum,如下:>>> null_ptr[0]traceback (most recent call last):
....
valueerror: null pointer access
>>>
>>> null_ptr[0] = 1234
traceback (most recent call last):
....
valueerror: null pointer access
>>>
from enum import enumc庫中有這樣乙個函式:class cand(enum):
x= 0
y= 1
int getdevinfo(deviceinfo *info,int counter,char *callback);在ctypes中傳遞結構體,只能傳遞結構體指標,不能傳遞例項物件,並且呼叫c庫中的函式引數必須以ctypes基本資料型別封裝才能呼叫,如下:
#呼叫c庫函式在這裡只介紹了一些ctypes模組常用的地方,感興趣的同學,可以參照官方教程:getdevinfo = clib .getdevinfo
#告訴ctypes資料型別
getdevinfo .argtypes= [pointer(deviceinfo ),c_int,pointer(c_char)]
t_callback = c_char()
#建立乙個結構體例項
t_devinfo = alldeviceinfo()
ret = getdevinfo (byref(t_devinfo ),c_int(3),byref(t_callback))
if(ret < 0):
print("call failed!")
else:
print("call success!")
Ctypes模組實現python加速執行
一 我們以fibonacci數列的例子來看看,python的執行時間 def fibonacci n if n 2 return 1 else return fibonacci n 1 fibonacci n 2 begin time.time print fibonacci 40 over tim...
python使用ctypes呼叫擴充套件模組的例項方法
楔子 我們知道python的執行效率不是很高,而且由於gil的原因,導致python不能充分利用多核cpu。一般的解決方式是使用多程序,但是多程序開銷比較大,而且程序之間的通訊也會比較麻煩。因此在解決效率問題上,我們會把那些比較耗時的模組使用c或者c 編寫,然後編譯成動態鏈結庫,windows上面是...
python中ctypes的使用
window下,python銜接c語言程式設計 本地安裝64位的python3.5,visual studio 2017 step1 安裝visual studio 2017,提供c語言編譯器 即msvc版本,另一版本是linux下的gcc step2 選擇x64的命令列 step3 輸入pip i...