如何立即 return 一条 WM_COPYDATA 消息并调用函数?
How to return a WM_COPYDATA message instantly and also call a function?
收到 WM_COPYDATA
消息时如何 return 响应 'instantly' 并调用函数?
我尝试使用 chrono
,但发送消息的应用仅在执行 sendCommand
函数后才收到响应。
#include <thread>
#include <future>
#include <iostream>
void sendCommand(std::chrono::seconds delay, std::string cmd)
{
std::this_thread::sleep_for( delay );
std::cout << "\nThe waited command is =" << cmd;
}
switch (msg)
{
case WM_COPYDATA:
{
OutputDebugStringW(L"\nWM_COPYDATA!");
PCOPYDATASTRUCT pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
//....
auto s1 = std::async(std::launch::async, sendCommand, std::chrono::seconds(5), "Command1");
return 1;
}
}
您要查找的是 lambda 函数 (https://en.cppreference.com/w/cpp/language/lambda),如下所示:
与std::thread:
std::thread t([]
{
sendCommand(std::chrono::seconds(5), "Command1");
});
与std::async
共享未来的解决方案,通过捕获它,将未来的生命周期延长到 lambda 的生命周期。
如果您使用的是 windows/msvc,那么使用线程池中的线程会有一点好处。否则只需使用线程解决方案。
#include <memory>
auto ft = std::make_shared<std::future<void>>();
*ft = std::async(std::launch::async, [ft]
{
sendCommand(std::chrono::seconds(5), "Command1");
});
在这个回答中,我假设您不想丢弃 WM_COPYDATA
发送的数据,但您希望您正在调用的函数能够访问此数据。
没有必要使用多线程来解决这个问题,如果你允许WM_COPYDATA
处理程序在returning之前复制数据。
WM_COPYDATA
处理程序可以做的是
- 为复制数据动态分配内存,
- 然后实际复制数据,
- 然后 post 一个用户定义的消息,其中包含指向使用
PostMessage
、 复制到消息队列的数据的指针
- 然后立即return,不调用函数处理数据。
稍后在线程的消息循环中处理用户定义的消息时,用户定义消息的处理程序可以调用函数来处理数据,然后在函数 returns 之后,释放动态分配的数据。
需要复制WM_COPYDATA
handler里面的数据,因为一旦handlerreturns.
指向数据的指针就失效了
如果您不介意阻塞接收到 WM_COPYDATA
的线程,您可以简单地使用 ReplyMessage()
:
#include <iostream>
void sendCommand(std::chrono::seconds delay, std::string cmd)
{
std::this_thread::sleep_for( delay );
std::cout << "\nThe waited command is =" << cmd;
}
switch (msg)
{
case WM_COPYDATA:
{
OutputDebugStringW(L"WM_COPYDATA!");
PCOPYDATASTRUCT pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
//...
ReplyMessage(1);
sendCommand(std::chrono::seconds(5), "Command1");
return 1;
}
}
收到 WM_COPYDATA
消息时如何 return 响应 'instantly' 并调用函数?
我尝试使用 chrono
,但发送消息的应用仅在执行 sendCommand
函数后才收到响应。
#include <thread>
#include <future>
#include <iostream>
void sendCommand(std::chrono::seconds delay, std::string cmd)
{
std::this_thread::sleep_for( delay );
std::cout << "\nThe waited command is =" << cmd;
}
switch (msg)
{
case WM_COPYDATA:
{
OutputDebugStringW(L"\nWM_COPYDATA!");
PCOPYDATASTRUCT pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
//....
auto s1 = std::async(std::launch::async, sendCommand, std::chrono::seconds(5), "Command1");
return 1;
}
}
您要查找的是 lambda 函数 (https://en.cppreference.com/w/cpp/language/lambda),如下所示:
与std::thread:
std::thread t([]
{
sendCommand(std::chrono::seconds(5), "Command1");
});
与std::async 共享未来的解决方案,通过捕获它,将未来的生命周期延长到 lambda 的生命周期。 如果您使用的是 windows/msvc,那么使用线程池中的线程会有一点好处。否则只需使用线程解决方案。
#include <memory>
auto ft = std::make_shared<std::future<void>>();
*ft = std::async(std::launch::async, [ft]
{
sendCommand(std::chrono::seconds(5), "Command1");
});
在这个回答中,我假设您不想丢弃 WM_COPYDATA
发送的数据,但您希望您正在调用的函数能够访问此数据。
没有必要使用多线程来解决这个问题,如果你允许WM_COPYDATA
处理程序在returning之前复制数据。
WM_COPYDATA
处理程序可以做的是
- 为复制数据动态分配内存,
- 然后实际复制数据,
- 然后 post 一个用户定义的消息,其中包含指向使用
PostMessage
、 复制到消息队列的数据的指针
- 然后立即return,不调用函数处理数据。
稍后在线程的消息循环中处理用户定义的消息时,用户定义消息的处理程序可以调用函数来处理数据,然后在函数 returns 之后,释放动态分配的数据。
需要复制WM_COPYDATA
handler里面的数据,因为一旦handlerreturns.
如果您不介意阻塞接收到 WM_COPYDATA
的线程,您可以简单地使用 ReplyMessage()
:
#include <iostream>
void sendCommand(std::chrono::seconds delay, std::string cmd)
{
std::this_thread::sleep_for( delay );
std::cout << "\nThe waited command is =" << cmd;
}
switch (msg)
{
case WM_COPYDATA:
{
OutputDebugStringW(L"WM_COPYDATA!");
PCOPYDATASTRUCT pcds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
//...
ReplyMessage(1);
sendCommand(std::chrono::seconds(5), "Command1");
return 1;
}
}