Warm tip: This article is reproduced from serverfault.com, please click

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

(python - How to use ctypes to call a DLL function with double underline function name?)

发布于 2020-12-10 13:05:45

我正在尝试使用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

我该如何处理情况?

Questioner
Zikikov
Viewed
11
Mark Tolonen 2020-12-11 14:17:31

也可以使用以下语法调用该函数,并且绕过混淆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仅具有一个调用约定,因此两者都可以工作,但是出于可移植性的考虑,请记住这一点。