[Closed] PostMessage does not handle 64-bit arguments properly?
Hello,
Environment: 64-bit Windows 10, 64-bit 3ds Max 2017.
Our 64-bit native (C++) renderer plugin is posting a message from a non-UI thread with the following code:
const UINT WM_TRIGGER_CALLBACK = WM_USER + 4764;
PostMessage(
GetCOREInterface()->GetMAXHWnd(),
WM_TRIGGER_CALLBACK,
reinterpret_cast<WPARAM>(func),
reinterpret_cast<LPARAM>(data));
The receiving function is defined as such:
void func(UINT_PTR param_ptr)
{
}
This is all 100% as per 3ds Max’s SDK documentation (section Executing Code in Main Thread).
The problem is that the 32 high bits of data get lost, i.e. they are cleared by the time func is called.
For example, if data is 0x00000001c36f3e60 (a pointer above the 4 GB limit) when calling PostMessage(), it ends up being equal to 0x00000000c36f3e60 inside func.
Basically it looks like 3ds Max is unable to transport 64-bit arguments in messages. Is that a known bug, or are we doing something wrong?
Best,
Franz
It must work. It’s the basic of the messaging system WPARAM and LPARAM are unsigned __int64 if you compile your plugin for x64 of course
That it must work, I agree Everything is compiled and running in 64-bit. I suspect that PostMessage() works fine, but that Max’s internal callback queue just doesn’t preserve all 64 bits of the LPARAM argument. The involved code is exactly the one listed in my initial post, it’s all there and I’m not sure it can be made any simpler. It does look like a bug.
must work, never had problems
what you do when receiving WM_TRIGGER_CALLBACK ?
or might be this, from MSN:
Message numbers in the second range (WM_USER through 0x7FFF) can be defined and used by an application to send messages within a private window class. These values cannot be used to define messages that are meaningful throughout an application because some predefined window classes already define values in this range.
so better use WM_APP+4764 instead of WM_USER
Hi @guruware, thanks for your input.
You mean, in my function func? Nothing, I have a breakpoint in that function and I just look at the param_ptr value in the debugger, and it has clearly lost the high 32 bits.
I don’t think I have much of a choice though, Max requires WM_USER + 4764 (as per the documentation) to trigger its delayed function call mechanism.
To be honest, by that point I’m pretty sure it’s a bug. It’s not that common to hit it, you need the last argument of PostMessage() to be either a pointer above the 4 GB limit or an integer bigger than 2^32-1. It’s also easily circumvented (we rebuilt this part using a global message queue protected by a mutex).
At this point I’m mostly just curious to know if anyone has ever hit this bug before.
Franz
tried it…
you are right, the high 32 bits are gone, maybe a leftover from updating max to x64
i will tell the devs
i’m using always a custom callback class to do some other things while my threads are running
never had any problems with that
well, it depends what you want to do in your callback function…
Hey Thomas, thanks for confirming the bug, glad that it got fixed!
We no longer rely on the second argument of PostMessage() so we’re good.
If anyone’s interested or need inspiration for a workaround, here’s our solution built around a global work queue:
https://github.com/appleseedhq/appleseed-max/blob/master/src/appleseed-max-impl/logtarget.cpp#L53-L150
Thanks!
Franz