DLL(Dynamic Link Library)动态链接库,是windows上常用的程序包类型。很多业务场景中需要制作和引用DLL。 这里举例说明Python调用DLL的方法,以及DLL中代码回调Python函数的方式。
1. CDLL和WinDLL
在Python中,常使用ctypes库进行与C/C++之间的数据类型的转换,以及DLL的调用。
在制作dll时,我们知道需要约定一种调用规则,调用规则通常是对于函数参数的入栈和清空方式的约定,而调用规则比较常用的有两种, __cdecl和__stdcall,简单来说,前者是C/C++的默认规则,后者是Windows上常用的规则。(关于两者的不同请参考如下链接,这里不展开说明了:
https://blog.csdn.net/colinchan/article/details/4478721)
在使用VS制作dll时,默认的规则是__cdecl,如果要采用__stdcall则需要显式调用。如:
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define API_DLL __declspec(dllexport)
#define CALL_TYPE __stdcall
//#define CALL_TYPE __cdecl
extern "C" {
API_DLL int CALL_TYPE dllDebug(int a, int * iParam, char * oParam);
API_DLL void CALL_TYPE dllRegisterPythonFunc(void * pyFuncPtr);
API_DLL int CALL_TYPE dllCallbackPythonFunc(void);
}
在Python中,使用ctypes库,对应__cdecl的DLL使用ctypes.CDLL方法引用;对应__stdcall的DLL则使用ctypes.WinDLL方法引用DLL:
def python_get_dll(winDll=False):
dllDir = "D:/PythonDll/Release/PythonDll.dll"
if winDll:
myDll = ctypes.WinDLL(dllDir)
else:
myDll = ctypes.CDLL(dllDir)
return myDll
2. Python调用DLL中的函数
在DLL中实现在1中声明的函数dllDebug,如下:
int CALL_TYPE dllDebug(int a, int * iParam, char * oParam) {
sprintf(oParam,"Input:[%d %d %d]",iParam[0], iParam[1], iParam[2]);
return a + iParam[0];
}
此函数中,三个参数,分别是一个int,一个