First a background question:
In general, what is the difference between int
and IntPtr
? My guess is that it is an actual object rather than a
int
is 32 bits long. IntPtr
is as long as a pointer for your architecture. Therefore, a pointer can be stored into an int
only on 32 bit systems, while it can always be stored in an IntPtr
.
Notice that your "int as a return value" example does not use an int
to hold a pointer, but just to hold a numeric value. This does not mean that an int
is automatically the correct size though: the author of that P/Invoke signature should have gone to the documentation for GetForegroundWindow and see that it returns a HWND
.
Then, from windef.h
in the Platform SDK (or this MSDN page) we can see that a HWND
is a HANDLE
which is a PVOID
which is... a pointer!
Therefore, as far as I can tell, that signature is wrong, as the size of the return value of GetForegroundWindow
depends on the architecture. Thus, it should also be an IntPtr
.
Update:
While it can be inferred from the above, I think it's worthwhile to explicitly point out that:
int
instead of IntPtr
in 32-bit applications will never cause a problem, even if they run on 64-bit Windows; since most applications are 32-bit at this point in time, this will let you get away such mistakes very often.int
instead of IntPtr
in 64-bit applications is not guaranteed to cause problems, since it is quite possible that in practice the values being encountered will fit in the 32 bits of the int
. This further lessens the probability that a mistake will manifest as an application error.Therefore, for an error to actually manifest there are three conditions that have to be satisfied at the same time:
int
is used where an IntPtr
should be.int
is actually larger than 32 bits.