我正在尝试使用Python 3.8和该ctypes
模块在DLL中调用函数。
DLL中的函数名称为__apiJob()
。请注意,此功能以双下划线开头。
我想在自定义对象中调用它,例如:
class Job:
def __init__(self,dll_path):
self.windll = ctypes.WinDLL(dll_path)
def execute(self):
self.windll.__apiJob()
a = Job('api64.dll')
a.execute()
但是,由于函数名称以双下划线开头,在Python中使用名称修饰函数,因此它将被视为私有方法。因此,在运行此脚本时,__apiJob
会将重命名为,_Job_apiJob
从而导致错误: "_Job__apiJob" not found
。
我该如何处理情况?
也可以使用以下语法调用该函数,并且绕过混淆Python适用于类实例的“ dunder”属性:
self.windll['__apiJob']()
下面的例子:
测试文件
extern "C" __declspec(dllexport)
int __apiJob() {
return 123;
}
test.py
import ctypes
class Job:
def __init__(self):
dll = ctypes.CDLL('./test')
self.apiJob = dll['__apiJob'] # bypass "dunder" class name mangling
self.apiJob.argtypes = ()
self.apiJob.restype = ctypes.c_int
def execute(self):
return self.apiJob()
a = Job()
result = a.execute()
print(result)
输出:
123
顺便说一句,WinDLL
用于DLL__stdcall
在32位DLL中使用调用约定声明函数。 CDLL
用于默认的__cdecl
调用约定。64位DLL仅具有一个调用约定,因此两者都可以工作,但是出于可移植性的考虑,请记住这一点。