如何使用postThreadMessage来传递一个结构体

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

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

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

typedef LONG_PTR LPARAM; 

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

关于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!!! } 

但是你可以尝试这个解决方法:

 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 } 

事后 :请注意,PostThreadMessage可能会失败…并且你不想泄漏一个shared_ptr。

根据我的经验,通常最好使用std :: deque来保存数据,并使用PostThreadMessage来通知那里有数据。 这样你永远不会失去一个对象! 因人而异

我遇到过使用Qt QModelIndex类的类似情况,它使用void*保存数据,但是我使用shared_ptr管理指向它的数据。

为了避免直接取消引用void* ,这可能指向不再存在的对象,我使用从void*weak_ptr的映射。 所有由QModelIndexes引用的对象都存储在地图中。 当需要解引用void* ,我使用void*作为key来从map中检索相应的weak_ptr ,然后将weak_ptr转换成shared_ptr 。 然后shared_ptr或者等于void*或者它是NULL ,并且你也可以获得类型安全性。

请注意,我的解决方案不必处理您提到的并发问题,但是您可能可以根据自己的情况进行调整。 您可以使用lparam将原始指针存储到您的对象,然后使用映射将原始指针转换为智能指针。 用互斥体保护地图,你可能在那里。