Hide a value in parameter of CreateThread()

I'm looking for a direct way to pass a single UINT to a CreateThread()

I know I can hide a socket in a CreateThread(), like this:

CreateThread(0,0,MyThread,(LPVOID)MySocket,0,&nThreadID);

and then inside the thread I can convert it back

SOCKET MySocket = (SOCKET)lpparam;

Microsoft uses a structure to submit a whole set of values, here
https://docs.microsoft.com/en-us/windows/win32/procthread/creating-threads
but that obviously has the problem that the values might get lost before the thread gets to them, meaning the calling process has to wait for the thread or the calling process has to alloc memory and the thread has to clean up.

Isn't there a simple way to do with an UINT the same one can do with a socket?
Am I missing something?
CreateThread(0,0,MyThread,(LPVOID)(&MyUINT),0,&nThreadID);
Yes you are missing something.

&MyUINT points to an address the calling process has created, meaning the calling process has to wait until the thread has picked up the value from that address and that's the part I would like to avoid.

Imagine it like this:

void SomeFunction()
{
UINT i = 17;
CreateThread(0,0,MyThread,(LPVOID)(&i),0,&nThreadID);
return;
}

The thread will never get a chance to read the value, because by the time the thread is running the value is long out of scope.
Last edited on
> I'm looking for a direct way to pass a single UINT to a CreateThread()
Well if you know how to do this
CreateThread(0,0,MyThread,(LPVOID)MySocket,0,&nThreadID);

Then there is no problem doing this.
CreateThread(0,0,MyThread,(LPVOID)MyUint,0,&nThreadID);

It's just (ab)using the low level C casting for any bit of data where sizeof(data)<=sizeof(void*)

You just do this in the called thread.
UINT MyVal = (UINT)lpparam;

Or you upgrade to at least C++11 and use this.
https://www.cplusplus.com/reference/thread/
Then all the grubby detail is hidden from you.
I am aware I'm kinda abusing it, but I've done that for 15 years by now with the socket and never had a problem, it just works nice and easy.
After all this is not a commercial project, it's a hobby for myself and a handful of friends.

But this one my compiler (MinGW/GCC++) doesn't like

CreateThread(0,0,MyThread,(LPVOID)MyUint,0,&nThreadID);
...
UINT MyVal = (UINT)lpparam;

giving me the error:

cast to pointer from integer of different size [-Wint-to-pointer-cast]

No I'm not using CRT.
Last edited on
So what is an UINT on your system?

> or the calling process has to alloc memory and the thread has to clean up.
And what's wrong with that?

It's robust and extensible, and you don't have to worry about your pseudo types like UINT suddenly becoming a different size to a pointer, just because you change compiler.

There is nothing "wrong" with that, but I don't need it extensible, I find it an exaggerated effort in case I need to pass on just one single value.
Of course I can (in fact I currently do) create some values in the calling process and point to them in CreateThread() and of course I can delete those values from the thread, it would just be much easier and shorter in the code if I could pass on the value directly.
It feels a bit like going to the store at the street corner for a bottle of milk and driving those 50 meters with a 36 ton truck, rather than walk on foot.
Last edited on
It looks like you're compiling for 64 bits. LPVOID will be 64 bits but UINT will probably be 32 bits. If the error is on the CreateThread(), then try this:

 
CreateThread(0, 0, MyThread, (LPVOID)(unsigned long long)MyUint, 0, &nThreadID);

Yes, that works.
Gives me an additional or new problem, but that I can work out myself and would be off topic here.
Thanks to all of you for the input.
> It feels a bit like going to the store at the street corner for a bottle of milk and
> driving those 50 meters with a 36 ton truck, rather than walk on foot.
Or you went to buy two bottles of milk, only to find out that your shopping bag was only big enough for one. But since you cast away any possibility of diagnostics, you leave the store happy, only to be disappointed to see one bottle when you get back home.

At some point, you'll get bored of hit-and-miss cowboy programming techniques which only work occasionally, and move to something which works out of the box every single time without having to micro-manage everything.
At some point, you'll get bored of hit-and-miss cowboy programming techniques which only work occasionally, and move to something which works out of the box every single time without having to micro-manage everything.


Agree. :) It's 'kludges' like that that make the transition 32/64 bit so hard and introduce subtle errors that are hard to find.
Topic archived. No new replies allowed.