在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中文網其他相關文章!

SlicingaPythonlistisdoneusingthesyntaxlist[start:stop:step].Here'showitworks:1)Startistheindexofthefirstelementtoinclude.2)Stopistheindexofthefirstelementtoexclude.3)Stepistheincrementbetweenelements.It'susefulforextractingportionsoflistsandcanuseneg

numpyallowsforvariousoperationsonArrays:1)basicarithmeticlikeaddition,減法,乘法和division; 2)evationAperationssuchasmatrixmultiplication; 3)element-wiseOperations wiseOperationswithOutexpliitloops; 4)

Arresinpython,尤其是Throughnumpyandpandas,weessentialFordataAnalysis,offeringSpeedAndeffied.1)NumpyArseNable efflaysenable efficefliceHandlingAtaSetSetSetSetSetSetSetSetSetSetSetsetSetSetSetSetsopplexoperationslikemovingaverages.2)

列表sandnumpyArraysInpythonHavedIfferentMemoryfootprints:listSaremoreFlexibleButlessMemory-效率,而alenumpyArraySareSareOptimizedFornumericalData.1)listsStorReereReereReereReereFerenceStoObjects,with withOverHeadeBheadaroundAroundaround64byty64-bitsysysysysysysysysyssyssyssyssysssyssys2)

toensurepythonscriptsbehavecorrectlyacrycrosdevelvermations,分期和生產,USETHESTERTATE:1)Environment varriablesForsimplesettings,2)configurationfilesfilesForcomPlexSetups,3)dynamiCofforComplexSetups,dynamiqualloadingForaptaptibality.eachmethodoffersuniquebeneiquebeneqeniquebenefitsandrefitsandrequiresandrequiresandrequiresca

Python列表切片的基本語法是list[start:stop:step]。 1.start是包含的第一個元素索引,2.stop是排除的第一個元素索引,3.step決定元素之間的步長。切片不僅用於提取數據,還可以修改和反轉列表。

ListSoutPerformarRaysin:1)DynamicsizicsizingandFrequentInsertions/刪除,2)儲存的二聚體和3)MemoryFeliceFiceForceforseforsparsedata,butmayhaveslightperformancecostsinclentoperations。

toConvertapythonarraytoalist,usEthelist()constructororageneratorexpression.1)intimpthearraymoduleandcreateanArray.2)USELIST(ARR)或[XFORXINARR] to ConconverTittoalist,請考慮performorefformanceandmemoryfformanceandmemoryfformienceforlargedAtasetset。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

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

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver CS6
視覺化網頁開發工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。