如何立即 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 处理程序可以做的是

  1. 为复制数据动态分配内存,
  2. 然后实际复制数据,
  3. 然后 post 一个用户定义的消息,其中包含指向使用 PostMessage
  4. 复制到消息队列的数据的指针
  5. 然后立即return,不调用函数处理数据。

稍后在线程的消息循环中处理用户定义的消息时,用户定义消息的处理程序可以调用函数来处理数据,然后在函数 returns 之后,释放动态分配的数据。

需要复制WM_COPYDATAhandler里面的数据,因为一旦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;
    }
}