【发布时间】:2020-07-28 13:43:45
【问题描述】:
我正在尝试在 DLL 中调用以下函数,该函数(据我所知)将回调作为参数。
C# 定义:
//Error handler
public delegate int FPtrErrorHandler(int ErrorType, int MessageType, int WhomToInform, String ErrorMessage);
//Desired function to call
[ DllImport ( Globals.LibDLLPath, CallingConvention = CallingConvention.Cdecl ) ]
public static extern int OpenLib(String TempDirectory, Bool IfCleanTempDir, FPtrErrorHandler ErrorHandler);
根据this SO entry,我在下面创建了 Python 代码:
import ctypes as c
from ctypes import *
@c.WINFUNCTYPE(c.c_int, c.c_int, c.c_int, c.c_int, c.c_char_p)
def FPtrErrorHandler(ErrorIdentifier, ErrorMessageType, WhomToInform, ErrorMessage):
print(f'Error ID={ErrorIdentifier}, Type={ErrorMessageType}, WhomToInform={WhomToInform}, msg={ErrorMessage}')
return 0
lib = windll.LoadLibrary('path_to_dll')
_OpenLib = lib[163]
_OpenLib.restype = c_int
_OpenLib.argtypes = [c_char_p, c_bool, c_void_p]
def OpenLib(TempDirectory,IfCleanTempDir):
cb1 = FPtrErrorHandler
return _OpenLib(TempDirectory, IfCleanTempDir, cb1)
n = OpenLib(r:'c:\temp',c_bool(True))
不幸的是,我收到了可怕的消息
ArgumentError: argument 1: <class 'TypeError'>: wrong type
在此先感谢您帮助我。我真的很高兴学习 ctypes 以及如何使用 Python 与令人惊叹的 DLL 进行交互。
【问题讨论】:
-
我不确定python是如何与外部代码交互的,但是c#
FPtrErrorHandler已经定义了4个参数。但是你的 pythonFPtrErrorHandler只有 3 个参数。是不是错了? -
另外,
c.WINFUNCTYPE的第一个参数c.c_char_p似乎需要是返回类型。但是c#方法返回int,因此应该是c.c_int,对吧? -
好问题——我必须说我自己也不清楚。我假设
FPtrErrorHandler中的ErrorMessage 是一个输出参数,因此c.c_char_p作为c.WINFUNCTYPE的第一个参数。不过,我愿意接受有关更改内容的建议。 -
ErrorMessage绝对不是 outpur 参数,如果是的话,它会用out关键字进行注释。签名显示返回类型是int。 -
@Ackdari,根据您的反馈,我更改了当前显示的代码。但是,我仍然遇到同样的错误。