Функция WinMessage Win API выдает исключение (возможно, из-за неправильного обратного вызова) - PullRequest
0 голосов
/ 15 ноября 2018

Моя проблема, я думаю, связана с тем, что я пытаюсь связать функцию-член класса (не статическую) в качестве обратного вызова к функции 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)

1 Ответ

0 голосов
/ 15 ноября 2018

Windows API строго представлен как интерфейс C.Вы не можете передавать указатели нестатическим членам класса как обратные вызовы для любого Windows API (или функциональных объектов, возвращаемых std :: bind ).Компилятор уже говорил вам об этом, что, вероятно, привело к тому, что вы заставили компилятор замолчать, добавив (недопустимое) приведение.

Удалите приведение, и компилятор сообщит вам, передали ли вы указатель на функцию с правильнымподпись.Вы также можете безопасно удалить обработчики try / catch.Windows API никогда не вызовет исключение C ++ (см. Первый абзац).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...