Home > Article > Backend Development > How to call dll library in python
In some cases, C is needed to supplement efficiency in python. In practical applications, some data interaction is required. Using the ctypes module in Python, you can easily call Windows DLLs (including so files under Linux). This module will be explained in detail below (taking the Windows platform as an example). Of course, I assume that you already know how to write under Windows. A DLL is no problem.
Introducing the ctypes library
from ctypes import *
Assume that you already have a DLL (the name is add.dll), and the DLL has a cdecl (here The calling convention is emphasized because the export functions declared by the stdcall calling convention and the cdecl calling convention use different loading functions when loading using python, which will be explained later) The export function Add of the calling convention is added.
Related recommendations: "python video tutorial"
Create a Python file DllCall.py test:
from ctypes import * dll = CDLL("add.dll") print dll.Add(1, 102)
Result: 103
The above is a simple example. Let’s briefly talk about the calling process:
1. Loading DLL
As mentioned above, when loading, you should base on what calling convention the function you are about to call conforms to.
stdcall calling convention: two loading methods
Objdll = ctypes.windll.LoadLibrary("dllpath") Objdll = ctypes.WinDLL("dllpath")
cdecl calling convention: there are also two loading methods
Objdll = ctypes.cdll.LoadLibrary("dllpath") Objdll = ctypes.CDLL("dllpath") /*其实windll和cdll分别是WinDLL类和CDll类的对象。*/
2. Call the method in the dll
In 1 When loading the dll, a DLL object (assuming the name is Objdll) will be returned. This object can be used to call methods in the dll.
e.g. If there is a method named Add in the dll (note that if the method is declared by stdcall, if it is not an exported function declared in a def file or extern "C", the compiler will modify the function name. , please pay attention to this, I think you understand.)
Call: nRet = Objdll.Add(12, 15), which completes a call.
It seems that the call is very simple. Don’t just look at the appearance. Haha, this is because the Add function is too simple. Now assuming that the function requires you to pass in an int type pointer (int*), you can use byref in the library keyword to implement, assuming that the third parameter of the function being called is a pointer of type int.
intPara = c_int(9) dll.sub(23, 102, byref(intPara)) print intPara.value
If you want to pass in a char buffer pointer and buffer length, there are at least four methods:
# 方法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 basic types and type mapping tables implemented in ctypes
ctypes data type C data type
c_char char
c_short short
c_int int
c_long . ##The corresponding pointer type is followed by "_p", such as int* is c_int_p, etc.
To implement the structure in c language in python, you need to use classes.
4. The function in the DLL returns a pointer.
Although this is not a good programming method, the method of handling this situation is also very simple. In fact, all the addresses are returned, convert them to the corresponding python type, and then access them through the value attribute.
pchar = dll.getbuffer() szbuffer = c_char_p(pchar) print szbuffer.value
The Python code is as follows:
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.valueExample 2:
This example calls the createprocessA function in kernel32.dll to start a notepad process.
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))
The above is the detailed content of How to call dll library in python. For more information, please follow other related articles on the PHP Chinese website!