python如何呼叫dll函式庫
在python中某些時候需要C做效率上的補充,在實際應用中,需要做部分數據的交互。使用python中的ctypes模組可以很方便的調用windows的dll(也包括linux下的so等文件),下面將詳細的講解這個模組(以windows平台為例子),當然我假設你們已經對windows下怎麼寫一個DLL是沒有問題的。
引入ctypes函式庫
from ctypes import *
假設你已經有了一個的DLL(名字是add.dll),且該DLL有一個符合cdecl(這裡強調呼叫約定是因為,stdcall呼叫約定和cdecl呼叫約定聲明的導出函數,在使用python載入時使用的載入函數是不同的,後面會有說明)呼叫約定的導出函數Add。
相關推薦:《python影片教學》
建立一個Python檔DllCall.py測試:
from ctypes import * dll = CDLL("add.dll") print dll.Add(1, 102)
結果:103
#上面是一個簡單的例子。下面簡單聊聊呼叫流程:
1、載入DLL
上面已經說過,載入的時候要根據你將要呼叫的函數是符合什麼呼叫約定的。
stdcall呼叫約定:兩個載入方式
Objdll = ctypes.windll.LoadLibrary("dllpath") Objdll = ctypes.WinDLL("dllpath")
cdecl呼叫約定:也有兩種載入方式
Objdll = ctypes.cdll.LoadLibrary("dllpath") Objdll = ctypes.CDLL("dllpath") /*其实windll和cdll分别是WinDLL类和CDll类的对象。*/
2、呼叫dll中的方法
在1中載入dll的時候會回傳一個DLL物件(假設名字叫Objdll),利用該物件就可以呼叫dll中的方法。
e.g.如果dll中有個方法名字叫Add(注意如果經過stdcall宣告的方法,如果不是用def檔案宣告的匯出函式或extern “C” 宣告的話,編譯器會對函式名稱進行修改,這個要注意,我想你們懂的。)
呼叫:nRet = Objdll.Add(12, 15) 即完成一次呼叫。
看起來呼叫似乎很簡單,不要只看表象,呵呵,這是因為Add這個函數太簡單了,現在假設函數需要你傳入一個int型別的指標(int*),可以透過函式庫中的byref關鍵字來實現,假設現在所呼叫的函數的第三個參數是個int型別的指標。
intPara = c_int(9) dll.sub(23, 102, byref(intPara)) print intPara.value
如果要傳入一個char緩衝區指針,和緩衝區長度,方法至少有四種:
# 方法1 szPara = create_string_buffer('/0'*100) dll.PrintInfo(byref(szPara), 100); print szPara.value # 方法2 sBuf = 'aaaaaaaaaabbbbbbbbbbbbbb' pStr = c_char_p( ) pStr.value = sBuf #pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value dll.PrintInfo(pStr, len(pStr.value)) print pStr.value # 方法3 strMa = "/0"*20 FunPrint = dll.PrintInfo FunPrint.argtypes = [c_char_p, c_int] #FunPrint.restypes = c_void_p nRst = FunPrint(strMa, len(strMa)) print strMa,len(strMa) # 方法4 pStr2 = c_char_p("/0") print pStr2.value #pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value dll.PrintInfo(pStr2, len(pStr.value)) print pStr2.value
3、C基本型別和ctypes中實作的型別對應表
ctypes資料類型 C資料類型
c_char short
c_int long
c_ulong float
c_double void
對應的指標型別是在後面加上"_p",如int*是c_int_p等等。
在python中要實作c語言中的結構,需要用到類別。
4、DLL中的函數傳回一個指標。
雖然這不是個好的程式設計方法,不過這種情況的處理方法也很簡單,其實回傳的都是地址,把他們轉換對應的python類型,再透過value屬性存取。
pchar = dll.getbuffer() szbuffer = c_char_p(pchar) print szbuffer.value
5、處理C中的結構體類型
為什麼把這個單獨提出來說呢,因為這個是最麻煩也是最複雜的,在python裡面申明一個類似c的結構體,要用到類,而這個類別必須繼承自Structure。
範例:
Python程式碼如下:
def CreateGUID(): """ 创建一个全局唯一标识符 类似:E06093E2-699A-4BF2-A325-4F1EADB50E18 NewVersion """ try: # dll path strDllPath = sys.path[0] + str(os.sep) + "createguid.dll" dll = CDLL(strDllPath) b = dll.newGUID() a = c_char_p(b) except Exception, error: print error return "" return a.value
範例2:
這個範例是呼叫kernel32.dll中的createprocessA函數來啟動一個記事本進程。
from ctypes import * # 定义_PROCESS_INFORMATION结构体 class _PROCESS_INFORMATION(Structure): _fields_ = [('hProcess', c_void_p), ('hThread', c_void_p), ('dwProcessId', c_ulong), ('dwThreadId', c_ulong)] # 定义_STARTUPINFO结构体 class _STARTUPINFO(Structure): _fields_ = [('cb',c_ulong), ('lpReserved', c_char_p), ('lpDesktop', c_char_p), ('lpTitle', c_char_p), ('dwX', c_ulong), ('dwY', c_ulong), ('dwXSize', c_ulong), ('dwYSize', c_ulong), ('dwXCountChars', c_ulong), ('dwYCountChars', c_ulong), ('dwFillAttribute', c_ulong), ('dwFlags', c_ulong), ('wShowWindow', c_ushort), ('cbReserved2', c_ushort), ('lpReserved2', c_char_p), ('hStdInput', c_ulong), ('hStdOutput', c_ulong), ('hStdError', c_ulong)] NORMAL_PRIORITY_CLASS = 0x00000020 #定义NORMAL_PRIORITY_CLASS kernel32 = windll.LoadLibrary("kernel32.dll") #加载kernel32.dll CreateProcess = kernel32.CreateProcessA #获得CreateProcess函数地址 ReadProcessMemory = kernel32.ReadProcessMemory #获得ReadProcessMemory函数地址 WriteProcessMemory = kernel32.WriteProcessMemory #获得WriteProcessMemory函数地址 TerminateProcess = kernel32.TerminateProcess # 声明结构体 ProcessInfo = _PROCESS_INFORMATION() StartupInfo = _STARTUPINFO() fileName = 'c:/windows/notepad.exe' # 要进行修改的文件 address = 0x0040103c # 要修改的内存地址 strbuf = c_char_p("_") # 缓冲区地址 bytesRead = c_ulong(0) # 读入的字节数 bufferSize = len(strbuf.value) # 缓冲区大小 # 创建进程 CreateProcess(fileName, 0, 0, 0, 0, NORMAL_PRIORITY_CLASS,0, 0, byref(StartupInfo), byref(ProcessInfo))
以上是python如何呼叫dll函式庫的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。
