how to use postThreadMessage to pass a struct

本小妞迷上赌 提交于 2019-12-23 13:09:09

问题


I want to use windows's message queue facilities to send a struct to another thread. But I find out that the postthreadmessage function only provide two integer parameters, lparam and wparam for me to pass arguments.So I decide to put the address of the struct in lparam. Is this the correct way windows use to pass struct?

And I intend to use boost::shared_ptr to hold the address of struct in both the receiver thread and sender thread. I doubt that when the two shared_ptrs goes out of scope, will the struct be freed twice? I can not figure out a way to ensure the struct allocated on heap will be 100% freed, Any ideas?


回答1:


To the first question, yes, LPARAM is intended to be used as an integer or a pointer. That is clear from the definition:

typedef LONG_PTR LPARAM;

That is an integer long enough to hold a pointer.

About the shared_ptr thing, you are right, if you pass the raw pointer and wrap it into another shared_ptr you will free it twice:

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

But you can try this workaround instead:

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
}

AFTERTHOUGHT: Note that PostThreadMessage may fail... and you don't want to leak a shared_ptr.

In my experience it is generally better to use a std::deque to hold the data and use the PostThreadMessage to notify that there is data there. In this way you'll never lose an object! YMMV




回答2:


I've come across a similar situation using the Qt QModelIndex class, which holds data using a void*, but I manage the data it's pointing to using shared_ptr.

To avoid dereferencing the void* directly, which may be pointing to a no longer existing object, I use a map from void* to weak_ptr. All the objects that are referenced by QModelIndexes are stored in the map. When time comes to dereference a void*, I use the void* as a key to retrieve the corresponding weak_ptr from the map, then convert the weak_ptr into a shared_ptr. The shared_ptr is then either equal to the void* or it is NULL, and you get type safety as well.

Note that my solution did not have to deal with the concurrency issues that you mention, but you may be able to adapt it to your situation. You could use the lparam to store the raw pointer to your object, and then use the map to convert from a raw to a smart pointer. Protect the map with a mutex and you may be there.



来源:https://stackoverflow.com/questions/7130633/how-to-use-postthreadmessage-to-pass-a-struct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!