如何在 ctypes 中接收来自.dll的回调函数消息?



我正在尝试使用Ctypes调用.dll函数。 我有一个麻烦是获取回调函数值。 如果我调用回调函数,该函数不会给出值。 我的 python 代码有什么问题?

void __stdcall callbackmessage(int msgT, char* msg, void* data)
typedef void (__stdcall *CALLBACK)(int, char*, void*);
extern "C" _declspec(dllimport) void    __stdcall callbackfunc(CALLBACK callback, void* userdata);
import sys, ctypes
from ctypes import *
from ctypes import wintypes, POINTER
Load_DLL = WinDLL("test.dll")
sys.stdout = open('stdout.txt', 'w')
CONNECT= 4116
DISCONNECTED = 4113
def callbackmessage(msgT, msg, data):
if msgT == 4113:
print (b"disconnected!")
elif msgT == 4116:
print ("Connect!!")

CALLBACK = WINFUNCTYPE( c_int, POINTER(c_char), POINTER(c_void_p))
callbackfunc = Load_DLL.callbackfunc
callbackfunc.argtypes = [CALLBACK, c_void_p]
callbackfunc.restype = c_void_p
CALLBACKMESSAGE = CONNECT|DISCONNECTED
messageprocess = CALLBACK(callbackmessage)
callbackfunc(messageprocess, CALLBACKMESSAGE)

提及 [Python 3.Docs]: ctypes - Python 的外部函数库。

我看到代码有几个问题:

  1. 回调消息Python签名并不反映真实的签名(来自C)。要更正它,请将其更改为:

    CALLBACK = WINFUNCTYPE(None, c_int, POINTER(c_char), c_void_p)  # Adding 1st arg which is the return type; 3rd arg might also be c_char_p
    
  2. 我不确定callbackfunc如何解释它的第二个参数,但将CALLBACKMESSAGE放在那里似乎是错误的。我会这样做:

    callbackfunc(messageprocess, byref(c_int(CALLBACKMESSAGE)))
    
  3. 你确定(在C中)回调函数是_declspec(dllimport)吗?我认为应该__declspec(dllexport)

  4. callbackfunc.restype = None(次要)。void 和void指针 (c_void_p)不是一回事

  5. 最后但并非最不重要的一点是:这是一个逻辑错误:CALLBACKMESSAGE = CONNECT | DISCONNECTED这将产生一个值4117,如果这将是回调消息的 1starg,它不会打印任何内容。因此,选择一个值(例如CALLBACKMESSAGE = CONNECT)

最新更新