python - 如何在 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 的外部函数库。
我看到代码有几个问题:
callbackmessage的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
我不确定callbackfunc如何解释其第二个参数,但将CALLBACKMESSAGE放在那里似乎是错误的。我会这样做:
callbackfunc(messageprocess, byref(c_int(CALLBACKMESSAGE)))
你确定(在C中)callbackfunc是
_declspec(dllimport)
吗?我认为应该是__declspec(dllexport)
callbackfunc.restype = None
(次要的)。void和void指针 ( c_void_p )不是一回事最后但同样重要的是:这是一个逻辑错误:
CALLBACKMESSAGE = CONNECT | DISCONNECTED
这将产生一个值4117,如果这将是callbackmessage的第一个参数,它不会打印任何东西。所以,选择一个值(例如CALLBACKMESSAGE = CONNECT
)
推荐阅读
- r - 如果记录与其他数据框重复,则改变数据框
- python - JSON查询:python中的日期时间验证
- excel - Google Apps 脚本 - 将 xlsx 转换为覆盖现有文件的表格
- python-3.x - 抓取网页上的特定表格,但每次都是空的
- git - 赫斯基钩子不在 Lerna monorepo 中运行
- c# - 如何自动更新 DataGridViewColumn?
- javascript - 使用 ASP.NET Razor 的 Ajax POST
- android - 如何在 RecyclerView 上使用 Firebase 存储显示多个用户的图像
- java - 接收数据时如何以图形方式更改数字?
- python - .map_diag(plt.hist,bins=30) - 对角线上没有直方图