How to use postThreadMessage to pass structure

I want to use the Windows Message Queuing tool to send a structure to another thread. But I find out that the postthreadmessage function provides only two integer parameters: lparam and wparam for passing arguments. So I decided to put the address of the structure in lparam. Is this the correct way to use windows for a struct structure?

And I intend to use boost :: shared_ptr to store the structure address both in the receiver stream and in the sender stream. I doubt that when two shared_ptrs go out of scope, will the structure be freed twice? I cannot find a way to guarantee that the structure allocated to the heap will be 100% freed. Any ideas?

+4
source share
2 answers

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

typedef LONG_PTR LPARAM; 

This is an integer long enough to hold the pointer.

About doing shared_ptr, you are right, if you pass the raw pointer and wrap it in 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 a 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 } 

AFTER REPAIR . Note that PostThreadMessage may fail ... and you do not want shared_ptr to leak.

In my experience, it is generally best to use std :: deque to store data and use PostThreadMessage to notify if data is there. This way you will never lose an object! Ymmv

0
source

I came across a similar situation using the Qt QModelIndex class, which stores data using void* , but I manage the data indicating the use of shared_ptr .

To avoid dereferencing void* directly, which might point to a non-existing object, I use a map from void* to weak_ptr . All objects referenced by QModelIndexes are saved on the map. When it comes time to dereference void* , I use void* as the key to extract the corresponding weak_ptr from the map, then convert weak_ptr to shared_ptr . shared_ptr then is either equal to void* , or it is NULL , and you also get type safety.

Please note that my solution did not have to deal with the concurrency problems you mentioned, but you can adapt it to your situation. You can use lparam to store the raw pointer to your object, and then use the map to convert from raw to smart pointer. Protect the card with the mutex, and you can be there.

0
source

All Articles