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?
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