如何使用ctypes调用带有双下划线函数名的DLL函数?

How to use ctypes to call a DLL function with double underline function name?

我正在尝试使用 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中有mangling function这个名字,会被认为是私有方法。因此,当 运行 这个脚本时, __apiJob 将被重命名为 _Job_apiJob 从而导致错误: "_Job__apiJob" not found.

我该如何处理?

该函数也可以使用以下语法调用,并绕过混淆 Python 适用于 class 个实例的“dunder”属性:

self.windll['__apiJob']()

示例如下:

test.cpp

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 用于在 32 位 DLL 中使用 __stdcall 调用约定声明函数的 DLL。 CDLL 用于默认的 __cdecl 调用约定。 64 位 DLL 只有一个调用约定,因此两者都可以,但为了可移植性请记住这一点。