您現在的位置是:首頁 > 音樂首頁音樂

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

由 編碼那些事 發表于 音樂2023-02-06
簡介DLL函式的呼叫——函式引數為字串情況例1:如對於下面的函式,返回一個輸入字串的位元組長度,其函式C語言的實現程式碼如下:在Python中的呼叫程式碼如下:其中,第33行使用c_char_p定義了一個指向char型的指標變數pStr,並賦初

怎麼用指標實現數值調換

在Python語言中,可以使用ctypes模組呼叫其它如C++語言編寫的動態連結庫DLL檔案中的函式,在提高軟體執行效率的同時,也可以充分利用目前市面上各種第三方的DLL庫函式,以擴充Python軟體的功能及應用領域,減少重複編寫程式碼、重複造輪子的工作量,這也充分體現了Python語言作為一種膠水語言所特有的優勢。

這次以具體的例子講一下在Python中,如何使用ctypes模組呼叫DLL中的庫函式。本文的程式設計系統環境是win7 64位,Python使用的版本是python2。7。14。

由於DLL中函式中傳遞的引數型別比較多樣化,擬打算分三次講解這部分內容,這次先講傳遞數值、指標與字串引數的情況,後面再分兩次講解傳遞結構體、數值陣列等型別的情況。

DLL檔案的載入

假定已經有了一個DLL檔案“MyDll。dll”,其函式約定的呼叫方式為C呼叫(cdecl)方式,則Python中載入該dll檔案的程式碼如下:

其中,第1行是引入ctypes模組,第2行是採用C呼叫約定載入“MyDll。dll”檔案,並將返回值賦給dll變數,後續呼叫該DLL檔案中的函式時,會使用該變數定義要使用的具體函式。

另外,需要說明的是,若DLL函式的呼叫約定是標準呼叫約定(stdcall)方式,則DLL檔案的載入程式碼改為如下:

dll = WinDLL(‘MyDll。dll’)

DLL函式的呼叫——函式引數為數值情況

如對於“MyDll。dll”檔案中的函式add,其函式宣告如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

該函式有兩個int型別的輸入引數數x和y,返回的兩個數的和。其C語言的實現程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

在Python中的呼叫方式如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

這個函式應該說是最簡單的一個函數了,在第17行,直接使用第一步載入DLL後返回的名稱dll,後面跟函式名字即可返回其值。

DLL函式的呼叫——函式引數為指標情況

對於上面的函式改進為add2,其函式C語言的實現程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

此時函式有三個指向int型別的指標引數x、y、z,z為x和y的和。

在Python中的呼叫方式如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

其中,第20-22行定義了3個int型的變數x、y和z,初始值分別為2,3,0。第23行呼叫add2函式時,使用byref指明引數傳遞時為引用傳遞,對應著C語言的指標傳遞。函式執行後,使用z。value即可檢視z的值。

也可以使用下面的程式碼呼叫:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

上面程式碼中,第23-24行,在使用add2函式時,先將函式賦給一個變數add2,然後對其輸入輸出引數進行單獨宣告,使用POINTER宣告為這三個引數為指向int型別的指標變數。

DLL函式的呼叫——函式引數為字串情況

例1:如對於下面的函式,返回一個輸入字串的位元組長度,其函式C語言的實現程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

在Python中的呼叫程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

其中,第33行使用c_char_p定義了一個指向char型的指標變數pStr,並賦初值為’abcdef’,第34行將其傳入GetStringLength函式返回其長度。

也可以使用下面程式碼呼叫:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

將GetStringLength函式的輸入輸出引數分別使用argtypes和restype單獨進行宣告。

例2:如對於下面的函式,輸入輸出皆為字串指標,函式的功能是對於輸入pStr1賦值為“StrIn”,對於輸出返回一個指向字串常量“strOut”的指標,其函式C語言的實現程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

在Python中的呼叫程式碼如下:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

在上面程式碼中,同樣分別對輸入輸出引數進行了宣告。對於輸入引數pStr,使用create_string_buffer函式定義了一個字串緩衝區。對於返回值pChar,在列印輸出結果時,將其強制轉換為c_char_p型別,取其value值即可。

完整的測試程式碼

完整的測試程式碼如下圖所示:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

執行結果如下圖所示:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

總結

這次的例子基本涵蓋了在Python中透過ctypes模組呼叫DLL函式時,傳遞數值、指標、字串型別引數時的大部分情況。要注意的是,使用ctypes對映C語言中的資料型別時,兩者必須完全一致。下面是Python的ctypes模組中資料型別與C語言中資料型別對照表:

Python程式設計提高:如何呼叫DLL函式之傳遞數值、指標與字串引數

歡迎加關注,共同交流。