Heim > Artikel > Backend-Entwicklung > So rufen Sie die DLL-Bibliothek in Python auf
In einigen Fällen ist C erforderlich, um die Effizienz in Python zu ergänzen. In praktischen Anwendungen ist eine gewisse Dateninteraktion erforderlich. Mithilfe des ctypes-Moduls in Python können Sie ganz einfach Windows-DLLs (einschließlich solcher Dateien unter Linux) aufrufen. Dieses Modul wird im Folgenden ausführlich erläutert (am Beispiel der Windows-Plattform gehe ich natürlich davon aus, dass Sie bereits wissen, wie das geht). Unter Windows schreiben ist kein Problem.
Einführung in die ctypes-Bibliothek
from ctypes import *
Angenommen, Sie haben bereits eine DLL (mit dem Namen add.dll) und die DLL hat ein cdecl (hier die Aufrufkonvention). wird hervorgehoben, da die von der stdcall-Aufrufkonvention und der cdecl-Aufrufkonvention deklarierten Exportfunktionen beim Laden mit Python unterschiedliche Ladefunktionen verwenden, was später erläutert wird.) Die Exportfunktion Add der Aufrufkonvention wurde hinzugefügt.
Verwandte Empfehlungen: „Python-Video-Tutorial“
Erstellen Sie eine Python-Datei DllCall.py-Test:
from ctypes import * dll = CDLL("add.dll") print dll.Add(1, 102)
Ergebnis: 103
Das Obige ist ein einfaches Beispiel. Lassen Sie uns kurz über den Aufrufvorgang sprechen:
1. Laden der DLL
Wie oben erwähnt, sollten Sie sich beim Laden darauf stützen, welcher Aufrufkonvention die Funktion entspricht, die Sie aufrufen möchten.
stdcall-Aufrufkonvention: zwei Lademethoden
Objdll = ctypes.windll.LoadLibrary("dllpath") Objdll = ctypes.WinDLL("dllpath")
cdecl-Aufrufkonvention: Es gibt auch zwei Lademethoden
Objdll = ctypes.cdll.LoadLibrary("dllpath") Objdll = ctypes.CDLL("dllpath") /*其实windll和cdll分别是WinDLL类和CDll类的对象。*/
2. Aufrufmethoden in DLL
in 1 Beim Laden In der DLL wird ein DLL-Objekt zurückgegeben (vorausgesetzt, der Name lautet Objdll). Dieses Objekt kann zum Aufrufen von Methoden in der DLL verwendet werden.
z.B. Wenn es eine Methode namens Add in der DLL gibt (beachten Sie, dass der Compiler Änderungen vornimmt, wenn die Methode durch stdcall deklariert wird, es sich nicht um eine exportierte Funktion handelt, die in einer Def-Datei oder extern „C“ deklariert ist). Bitte achten Sie darauf, ich denke, Sie verstehen )
Rufen Sie auf: nRet = Objdll.Add(12, 15) um einen Aufruf abzuschließen.
Es scheint, dass der Aufruf sehr einfach ist. Schauen Sie sich nicht nur das Aussehen an, das liegt daran, dass die Funktion „Add“ zu einfach ist. ), können Sie zur Implementierung byref im Bibliotheksschlüsselwort verwenden, vorausgesetzt, der dritte Parameter der aufgerufenen Funktion ist ein Zeiger vom Typ int.
intPara = c_int(9) dll.sub(23, 102, byref(intPara)) print intPara.value
Wenn Sie einen Zeichenpufferzeiger und eine Pufferlänge übergeben möchten, gibt es mindestens vier Methoden:
# 方法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-Basistypen und Typzuordnungstabellen, die in ctypes implementiert sind
ctypes Datentyp C Datentyp
c_char char
c_short short
c_int int
c_long long
c_ulong unsign long
c_float float.
c_double 🎜>Der entsprechende. Zeiger Typ wird mit angehängt „_p“, wie int* ist c_int_p usw.
Um die Struktur in C-Sprache in Python zu implementieren, müssen Sie Klassen verwenden.
4. Die Funktion in der DLL gibt einen Zeiger zurück.
Obwohl dies keine gute Programmiermethode ist, ist die Methode zur Handhabung dieser Situation auch sehr einfach. Tatsächlich werden alle Adressen zurückgegeben, in den entsprechenden Python-Typ konvertiert und dann über das Wertattribut darauf zugegriffen.
pchar = dll.getbuffer() szbuffer = c_char_p(pchar) print szbuffer.value
Beispiel:
Der Python-Code lautet wie folgt:
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
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))
Das obige ist der detaillierte Inhalt vonSo rufen Sie die DLL-Bibliothek in Python auf. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!