【问题标题】:Function does not work inside a class - function call missing argument list函数在类中不起作用 - 函数调用缺少参数列表
【发布时间】:2013-02-14 21:20:34
【问题描述】:

我已经构建了一个可以工作的键盘记录器,现在我想将它移到类中,这样我就可以在需要时重新使用它,甚至可以在 c# 等不同的语言上重新使用它,但是我遇到了错误,因为相同的代码在类中不起作用。

main.cpp(工作)

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

void main()
{
    HINSTANCE h_instance = GetModuleHandle(NULL);
    SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, h_instance, 0); // Works here
}

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    // Populate typedChars
    return NULL;
}

KeyboardHook.cpp(不工作)

class KeyboardHook
{
    stringstream typedChars;

    LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        // Populate typedChars
        return NULL;
    }

    KeyboardHook()
    {
        HINSTANCE h_instance = GetModuleHandle(NULL);
        SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, h_instance, 0); // Does not work
    }

public:
    std::string Get()
    {
        return typedChars.str();
    }

    void Clear()
    {
        typedChars.str(std::string());
        typedChars.clear();
    }
};

错误

C3867: 'KeyboardHook::KeyboardProc': function call missing argument list; use '&KeyboardHook::KeyboardProc' to create a pointer to member

所以我将它修改为SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardProc, h_instance, 0);,现在出现了不同的错误

C2276: '&' : illegal operation on bound member function expression

我也尝试过,但没有成功:

SetWindowsHookEx(WH_KEYBOARD_LL, (LRESULT)&KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, (LRESULT)KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHook::KeyboardProc, h_instance, 0);
SetWindowsHookEx(WH_KEYBOARD_LL, &KeyboardHook::KeyboardProc, h_instance, 0);

【问题讨论】:

    标签: c++ windows hook keylogger


    【解决方案1】:

    假设SetWindowsHookEx 应该采用函数指针(我永远无法理解horrible Windows API documentation),您需要将指向成员函数的指针绑定到应该调用它的对象。如果你想将它绑定到this 指向的对象(即你当时正在创建的KeyboardHook 对象),试试这个:

    using std::placeholders;
    SetWindowsHookEx(WH_KEYBOARD_LL,
      std::bind(&KeyboardHook::KeyboardProc, this, _1, _2, _3),
      h_instance, 0);
    

    或者,KeyboardProc 可以声明为静态成员函数,但这意味着它不能使用 typedChars 成员。

    【讨论】:

    • 我得到 C2039: 'placeholders' : is not a member of 'std'_1 .. _3 未定义。将它们设置为静态可以解决所有问题,但会产生巨大的问题 - 我无法在 stringstream 中添加挂钩笔画。
    • @Steve std::bind 是 C++11 的一部分——确保你的编译器支持它。还要确保你包括<functional>
    • 好吧,现在我确实添加了<functional>,它找到了std::bind,但仍然有错误,似乎没有任何效果。 C2664: 'SetWindowsHookExA' : cannot convert parameter 2 from 'std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' to 'HOOKPROC' 有什么想法吗?
    • WinAPI 是 C 编程接口,因此传递它的函数对象(std::bind 实际返回的内容)将不起作用。只有静态函数会。
    【解决方案2】:

    您必须将KeyboardProc 定义为静态成员

    static LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    ...
    }
    

    如果它必须并且可以在没有对象的情况下调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 2016-03-08
      • 2016-04-16
      相关资源
      最近更新 更多