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?
I've come across a similar situation using the Qt
QModelIndex
class, which holds data using avoid*
, but I manage the data it's pointing to usingshared_ptr
.To avoid dereferencing the
void*
directly, which may be pointing to a no longer existing object, I use a map fromvoid*
toweak_ptr
. All the objects that are referenced byQModelIndexes
are stored in the map. When time comes to dereference avoid*
, I use thevoid*
as a key to retrieve the correspondingweak_ptr
from the map, then convert theweak_ptr
into ashared_ptr
. Theshared_ptr
is then either equal to thevoid*
or it isNULL
, 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.
To the first question, yes, LPARAM is intended to be used as an integer or a pointer. That is clear from the definition:
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:
But you can try this workaround instead:
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