首页 > 解决方案 > GetMessage Win API 函数抛出异常(可能是由于错误的回调)

问题描述

我的问题我认为这是因为我尝试将类成员函数(非静态)绑定为函数的回调SetWindowsHookEx。我已经尝试过调试,但除了回调绑定之外,我无法获得任何其他有用的信息,我不知道有任何其他方式这样做。因此,在第一次调用该GetMessage函数时,我收到以下异常:An unhandled exception was encountered during a user callback..

我的问题是,如果异常的原因是我绑定HookLowLevel::KeyboardProc函数的方式以便我可以将它作为回调传递,那么这样做的正确方法是什么?如果不是,您认为引发异常的原因可能是什么?

我在其中进行回调绑定的GetMessage函数以及找到引发异常的函数的位置:

void HookLowLevel::attachHook()
{
    printf("Hooking the keyboard\n");
    auto callback = std::bind(&HookLowLevel::KeyboardProc, this);
    hook_ = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)(&callback), 0, 0);
    printf("%X\n", hook_);
    MSG msg{ 0 };
    try
    {
        while (GetMessage(&msg, NULL, 0, 0) != 0 && !windowChanged_)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    catch (const std::runtime_error& re)
    {
        std::cerr << "Runtime error: " << re.what() << std::endl;
    }
    catch (const std::exception &e)
    {
        std::cerr << "exception: " << e.what();
    }
}

这就是 KeyboardProc 的定义:

LRESULT CALLBACK HookLowLevel::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

标签: c++winapiboost

解决方案


Windows API 严格公开为 C 接口。您不能将指向非静态类成员的指针作为回调传递给任何Windows API(或std::bind返回的函数对象)。编译器已经告诉过您这一点,这可能导致您通过添加(无效)强制转换来使编译器静音。

删除强制转换,编译器会告诉您,您是否传递了具有正确签名的函数指针。您还可以安全地删除您的try/catch处理程序。Windows API 永远不会抛出 C++ 异常(见第一段)。


推荐阅读