首页 > 解决方案 > 将 lambda 作为 Windows CALLBACK 函数传递失败

问题描述

static std::function<LRESULT(int nCode, WPARAM wParam, LPARAM lParam)> keyProc =
        [](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
        return 1;
    };
    keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyProc, theApp.m_hInstance, NULL);

错误 C2664 'HHOOK SetWindowsHookExW(int,HOOKPROC,HINSTANCE,DWORD)': 无法将参数 2 从 'std::function' 转换为 'HOOKPROC' MFCTest d:\test\mfctest2\mfctest\keymaphooker.cpp 62

PS:为什么我用这么长的表达式而不是auto?因为我希望它是静态的。

我把它改成

auto keyProc =
        [this](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
         return 1;//return KeyboardProc(keyHook, keyMap, nCode, wParam, lParam);
    };

它不再起作用了。

错误 C2664: 'HHOOK SetWindowsHookExW(int,HOOKPROC,HINSTANCE,DWORD)': 无法将参数 2 从 'KeyMapHooker::StartHook::' 转换为 'HOOKPROC'

标签: c++11winapi

解决方案


无状态 lambda(例如您正在使用的)确实可以转换为指向函数的指针,因此可以用作CALLBACK. 但是,std::function 不能以这种方式转换。

注意 lambda 表达式的类型不是 std::function,它是一个未命名的类类型(lambda 表达式的闭包类型)。您可以使用以下方法捕获正确的类型auto(这对存储持续时间没有影响):

static auto keyProc =
        [](int nCode, WPARAM wParam, LPARAM lParam)->LRESULT {
        return 1;
    };
    keyHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyProc, theApp.m_hInstance, NULL);

推荐阅读