python呼叫c語言的庫(動態庫DLL)

2020-08-12 22:21:47

@真開心啊,聚精會神找一天錯誤沒找到,看個視訊摸摸魚就找到了

首先要明確的怎麼匯入

專案所需,需要使用pyqt寫介面,然後裡有涉及電機和攝像頭的呼叫,底層驅動是c語言寫好了,並導出了動態庫dll檔案。

匯入方法

可以使用ctypescffi方法匯入,不過好像資料都不多
我用的是ctypes
在python程式碼的頭部匯入庫

import ctypes
from ctypes import *
AMC = ctypes.cdll.LoadLibrary
lib_amc = AMC("./driver/amc4030/AMC4030.dll") #該檔案與python在同一目錄下
print("add AMC4030.dll succeed")

一般這樣就把動態鏈接庫匯入進去了。假設庫裡有一個函數,名字是

function(int a, int b)

然後開始呼叫庫裡的函數

lib_amc.function(1,2)

參數型別怎麼匹配

上面這個都是很簡單的匯入和呼叫方法,但是我們主要出現的問題是參數型別不匹配。比如報錯

TypeError: an integer is required (got type str

比如我dll庫裡有一個函數原型是

#define temp_SYSTEM 0
···
temp_GetInt( void* ; const wchar_t* , long long* ); //這是原形

temp_GetInt(a, L"count", &temp_count);//呼叫一般都是這樣,裏面涉及了長字串,指針,void*

是不是在python裡呼叫就蒙了。。。
衆所周知,L"count", 這樣count的型別是長字串型。也就是wchar_t。後面的&temp_count,也就是一個長整型取地址
ctypes就是做這個型別轉換的,這個時候就需要一個c型別和python型別對應成ctypes的表了
也就是你在python程式碼裡用ctypes型別代替c語言裡有但是python裡沒有的型別,比如指針是吧。

ctypes基本C相容數據型別對應表

c 型別 python 型別 ctypes 型別
c_bool _Bool bool (1)
c_char char 1-character bytes object
c_wchar wchar_t 1-character string
c_byte char int
c_ubyte unsigned char int
c_short short int
c_ushort unsigned short int
c_int int int
c_uint unsigned int int
c_long long int
c_ulong unsigned long int
c_longlong __int64 or long long int
c_ulonglong unsigned __int64 or unsigned long long int
c_size_t size_t int
c_ssize_t ssize_t or Py_ssize_t int
c_float float float
c_double double float
c_longdouble long double float
c_char_p char * (NUL terminated) bytes object or None
c_wchar_p wchar_t * (NUL terminated) string or None
c_void_p void * int or None

上面這個表就是對應了python裡的怎麼改C庫數據型別

指針怎麼改

指針的改法如下
給他加個byref

最後這麼呼叫的

FX = ctypes.cdll.LoadLibrary
lib_fx = FX("./driver/fx17/SpecSensor.dll")
nDeviceCount = 0
c_nDeviceCount = c_longlong(nDeviceCount)
lib_fx.SI_GetInt(0, c_wchar_p('DeviceCount'), byref(c_nDeviceCount))