这似乎只是一个 Windows 问题,但我的问题的本质实际上是 C++11(或 MS C++0x TR1)。它是关于传递std::function
对象及其生命周期的。
我想有一个通过 Windows PostMessage
API 异步执行的通用框架。这是当情况迫使我退出当前的消息处理并在消息队列中注册任务时。
该框架使用指向静态函数 (in WPARAM
) 的指针和指向LPARAM
包含“this”指针以及其他上下文的上下文的指针 (in) 运行良好。
我想把它提升到一个新的水平并使用绑定和函数结构。我在 Visual Studio 2010 上(即std::function
存在但 TR1)。
到目前为止,这就是我所拥有的:
我正在WM_ASYNC_TASK
通过教科书注册 a,并且我的 windows 程序(我实际上正在使用 WTL)运行良好。PostMessage
工作正常,消息最终将onAsyncTask
正确地按预期到达wparam
and lparam
。
const UINT WM_ASYNC_TASK = RegisterWindowMessage(L"Async-Task");
我有一个CPlugin
,这是我要发送任务的地方。我有CHiddenWindow
哪个是获取消息的 Window 实现。我希望将onAsyncTask
功能转发回CPlugin
. hwnd
是窗口的句柄。
在CPlugin
我有:
void CPlugin::ShowMessageBox( void* arg ) {
wchar_t* text = (wchar_t*)arg;
MessageBox( NULL, text, L"Title", MB_OK )
}
void CPlugin::Sender( ) {
std::function<void(void*)> f = std::bind( &CPlug::ShowMessagebox,
this,
std::placeholders::_1 );
PostMessage( hwnd, WM_ASYNC_TASK, (WPARAM)f, (LPARAM)"Hello!!" );
}
在 WM_ASYNC_TASK 消息处理程序的 CHiddenWindow 中,我有:
void CHiddinWindow::onAsyncTask( WPARAM wparam, LPARAM lparam, /* more arguments */ )
{
std::function<void(void*)> f = (std::function<void(void*)>)wparam;
void* arg = lparam;
f( arg );
}
问题:
- 目前,当我尝试将 f 强制转换为 WPARAM 时,编译器会抱怨
PostMessage
(WPARAM
基本上是很长的)。 - 如果我使用
f
:的地址,我可以(WPARAM)&f
。 - 这就提出了另一个关于 f 的生命周期的问题。我该如何保留它?
- 当通过
&f
(保持f
在外面Sender()
- 不是我的愿望)时,我在onAsyncHandler
尝试取消引用时遇到访问冲突f
。 - 关于生命周期,我可以将 f 置于
std::shared_ptr
某种控制之下吗? - 没有真正的理由将参数传递给 wparam 中的函数(在我的例子中是文本)。我认为应该有一种方法可以让
std::function
对象的文本部分,但语法失败。
正如我所说,我在可变参数模板之前使用 VS 2010。Microsoft 有 C++0x 的 TR1 实现。我正在寻找一个不包括 boost 的解决方案,因为它现在对我不可用。
谢谢!