为啥 Python 需要在 DLL 中使用 GetMessage 进行消息泵送而不是 Qt?

Posted

技术标签:

【中文标题】为啥 Python 需要在 DLL 中使用 GetMessage 进行消息泵送而不是 Qt?【英文标题】:Why is message pumping with GetMessage in DLL needed for Python but not Qt?为什么 Python 需要在 DLL 中使用 GetMessage 进行消息泵送而不是 Qt? 【发布时间】:2019-07-22 20:43:47 【问题描述】:

我有一个使用 Windows API 的 C++ DLL,它处理 HWND_MESSAGE 窗口创建/注册并通过RegisterDeviceNotification 注册事件通知。在 Qt 中,我只是设置了一个窗口并且不使用GetMessage,但是我的窗口进程回调会自动工作,所以我不使用GetMessage 循环来接收WM_DEVICECHANGE 的通知。我无需添加任何其他代码即可获得设备到达和移除。

但是,在 Python 中,我只是使用 ctypes 将 DLL 加载为 cdll,它可以工作:

__lib = ctypes.cdll.LoadLibrary("DevSystem.dll")

但是,我需要在我的 C++ DLL 中手动使用事件 GetMessage 循环来获取设备到达/移除通知。我必须手动创建一个循环才能使其工作,我不明白。

基本上,这些行是 Python 需要工作的唯一区别:

    MSG msg;
    while (GetMessage(&msg, hWnd, WM_DEVICECHANGE, WM_DEVICECHANGE))
    
        DispatchMessage(&msg);
    
    为什么它在 Qt 中默认工作? 为什么 Python 需要消息 循环获取通知?

【问题讨论】:

如果加载“DevSystem.dll”取决于PATH 环境变量,请注意,从 Python 3.8 开始,您需要通过 @987654321 将所需目录添加到安全 DLL 搜索路径@。更简单地说,如果它只依赖于在同一目录中找到它旁边的依赖DLL,只需使用“DevSystem.dll”的完全限定路径。如果您依赖于工作目录,请将其更改为“./DevSystem.dll”。 【参考方案1】:

为什么它在 Qt 中默认工作?

Qt 应用程序框架运行一个消息循环来为 UI 提供服务,而该消息循环也为您的回调提供服务。

为什么 Python 需要一个消息循环来获取通知?

您的 Python 程序不包含任何运行消息循环的内容,因此您需要显式地实现它。

【讨论】:

这是有道理的。我尝试过其他一些基于 C# 的环境,它们也不需要消息循环,因此可能正在发生类似的事情。我想我认为 Qt 的消息循环将在另一个线程上,并且无法将消息泵送到已加载的 DLL。 @karamazovbros,也许;也许不吧。每个线程都有一个消息队列。队列中的消息仅在GetMessagePeekMessage 调用中处理。 已发送消息(例如WM_DEVICECHANGE)在此调用中自动分派(因此它们被称为“非排队”,虽然从字面意义上说,所有消息都已排队),但已发布 消息(即“排队”消息)必须通过DispatchMessage 发送。如果您的窗口是由实现 Qt 消息循环的线程创建的,那么发送到您窗口的消息将在该线程调用 GetMessage 时自动分派。 @kar:消息处理的范围是线程,而不是模块。如果一个线程处理消息,这些消息将被分派到在同一线程上运行的 any 模块中的代码。

以上是关于为啥 Python 需要在 DLL 中使用 GetMessage 进行消息泵送而不是 Qt?的主要内容,如果未能解决你的问题,请参考以下文章

opencv中自带的dll和lib 为啥不能直接使用?

为啥 C# 需要注册 COM DLL 才能引用它?

为啥我的 Visual Studio 2013 项目需要 mfc100.dll?

为啥需要在具有 .dll 作为数据访问层的消费应用程序的 app.config 文件中声明连接字符串

为啥使用这个库需要它的内部头文件?

为啥有些程序需要 .lib 和 .dll 才能工作