正确传递 class' 成员地址并具有调用它的能力

Passing class' member address correctly with the ability of invoking it

我正在努力将成员的地址传递给另一个函数。 这是我正在尝试做的事情:

我有以下防御:

bool MyClass::FunctionName();

然后在我程序的某处执行以下命令:

::SendMessage(hWnd, WM_NULL, (WPARAM)this, (LPARAM)&MyFunction);

其中 this 代表 MyClass

一旦我的 WndProc 被执行,我尝试这个:

LRESULT CALLBACK MyClass::WndProc(_In_ HWND hWnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
    Myclass* pClass= (Myclass*)wParam;

    std::function<bool()> pFunc = std::bind(bool(&Myclass::MyFunction)&lParam, pClass);
    pFunc();
}

我收到的错误:

warning C4554: '&' : check operator precedence for possible error; use parentheses to clarify precedence

Error 3 error C2064: term does not evaluate to a function taking 1 arguments c:\program files (x86)\microsoft visual studio 12.0\vc\include\xrefwrap 58

嗯,这应该编译:

LRESULT CALLBACK MyClass::WndProc(_In_ HWND hWnd, _In_ UINT uMsg, 
                                  _In_ WPARAM wParam, _In_ LPARAM lParam)
{
     switch (uMsg)
     {
         case WM_METHOD_CALL:
             Myclass* pClass= static_cast<Myclass*>(wParam);

             typedef bool Myclass::pmf();
             const auto pointer_to_member_function = static_cast<pmf>(lParam);
             (pClass->*pointer_to_member_function)();
             break;
     }
}

你的问题是,虽然期望 WPARAM 是一个 class 指针是完全安全的,但 "pointer to member function" 是一个非常复杂的野兽(考虑第二个基数中的虚函数 class),并且通常比单个指针大 - 因此它不适合 LPARAM。

如果您想使用 SendMessage,您可以执行以下操作:

将 typedef 移动到 Myclass:

     typedef bool Myclass::pmf();  // Inside the definition of Myclass.

您程序中的某处:

Myclass::pmf ptr = &MyFunction;
::SendMessage(hWnd, WM_METHOD_CALL, (WPARAM)this, (LPARAM)&ptr);

然后在您的消息处理程序中:

LRESULT CALLBACK MyClass::WndProc(_In_ HWND hWnd, _In_ UINT uMsg, 
                                  _In_ WPARAM wParam, _In_ LPARAM lParam)
{
     Myclass* pClass= static_cast<Myclass*>(wParam);
     switch(uMsg)
     {
         case WM_METHOD_CALL:
             do_method_call(wParam, lParam);
             break;
     }
     return 0; // Or whatever.
}


void do_method_call(_In_ WPARAM wParam, _In_ LPARAM lParam)
{
     const auto pointer_to_member_function = *static_cast<Myclass::pmf*>(lParam);
     (pClass->*pointer_to_member_function)();
}