正确传递 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)();
}
我正在努力将成员的地址传递给另一个函数。 这是我正在尝试做的事情:
我有以下防御:
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)();
}