如何使用 postThreadMessage 传递结构

Jas*_*son 5 windows boost message-queue shared-ptr

我想使用 windows 的消息队列工具将结构发送到另一个线程。但是我发现postthreadmessage函数只提供了两个整型参数,lparam和wparam给我传递参数,所以我决定把struct的地址放在lparam里面。这是 Windows 用来传递结构的正确方式吗?

我打算使用 boost::shared_ptr 在接收者线程和发送者线程中保存 struct 的地址。我怀疑当两个 shared_ptrs 超出范围时,结构会被释放两次吗?我想不出一种方法来确保在堆上分配的结构将被 100% 释放,有什么想法吗?

rod*_*igo 0

对于第一个问题,是的,LPARAM 旨在用作整数或指针。从定义中可以清楚地看出:

typedef LONG_PTR LPARAM;
Run Code Online (Sandbox Code Playgroud)

这是一个足够长的整数来容纳一个指针。

关于shared_ptr的事情,你是对的,如果你传递原始指针并将其包装到另一个shared_ptr中,你将释放它两次:

shared_ptr<Thing> a;
PostThreadMessage(x, 0, (LPARAM)a.get());
...
LRESULT OnMessage(int msg, WPARAM wp, LPARAM lp)
{
    shared_ptr<Thing> p((Thing*)lp); //Bad!!!
}
Run Code Online (Sandbox Code Playgroud)

但您可以尝试以下解决方法:

shared_ptr<Thing> a;
PostThreadMessage(x, 0, new shared_ptr<Thing>(a)); //pointer to smart-pointer
...
LRESULT OnMessage(int msg, WPARAM wp, LPARAM lp)
{
    shared_ptr<Thing> *pp = (shared_ptr<Thing>*)lp;
    shared_ptr<Thing> p(*pp);
    delete pp; //no leak
}
Run Code Online (Sandbox Code Playgroud)

事后思考:请注意,PostThreadMessage 可能会失败......并且您不想泄漏shared_ptr。

根据我的经验,通常最好使用 std::deque 来保存数据并使用 PostThreadMessage 来通知那里有数据。这样你就永远不会丢失物体!青年MMV