Reputation: 349
How does this work?
I looked at this tutorial from here:
WNDPROC fWndProc = (WNDPROC)GetWindowLong(Msg.hwnd, GWL_WNDPROC);
From msdn it explains that GetWindowLong returns a LONG that is defined as just a long. This confuses me because it is converted into a function pointer (WNDPROC).
What happens when you convert a long into a function pointer? They are completely different things. How can the function pointer even work when a long isn't even a function?
Upvotes: 1
Views: 962
Reputation: 10417
A pointer is just address of variable; So it is presented by integer.
Standard says uintptr_t
and intptr_t
is compatible with pointers
#include <stdint.h>
int a;
int *pa = &a;
uintptr_t addr_of_a = (uintpt_t)pa;
In 32-bit system, sizeof(uintptr_t)
= sizeof(int *)
= 4
. In 64-bit system, they're 8
.
GetWindowLong
function is used for 32-bit system, so its return value's type is LONG
, which is 4 byte.
In 64-bit system, however, size of pointer is 8 byte. So microsoft deprecate GetWindowLong
, and you should use GetWindowLongPtr
and LONG_PTR
.
// the type of the return value of GetWindowLongPtr is LONG_PTR. So this code is safe and portable.
WNDPROC fWndProc = (WNDPROC)GetWindowLongPtr(Msg.hwnd, GWLP_WNDPROC);
Upvotes: 4
Reputation: 141628
It assumes you are running on a system where there is a bijection between all possible addresses of a function, and a subset of all non-trap representations of a long.
In other words, so long as there are at least as many possible LONG values as there are WNDPROC values then this can work.
Usually the compiler would just shovel the bits from the WNDPROC into the memory (or register) for the LONG within GetWindowLong, and then shovel them back out into the WNDPROC for the line that you show.
Upvotes: 1
Reputation: 3577
On a 32bit Windows, a LONG is a 32 bit value, which is the same size as an address. @Chris is right, it starts as a function pointer that gets converted as a long, then you typecast it as a function pointer.
If you look at the notes from MSDN, you'll notice that the GetWindowLongPtr()
has replaced the original call. It returns a LONG_PTR, which is the way Microsoft declares a long that has the same size as a pointer on the current process architecture. Basically, it will be a 32bit address with 32bit processes, but 64bit on 64bit processes.
Upvotes: 1