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 value like an int
or byte
is. Assuming that is true:
So they are not the same. Yet I see handles represented as both.
Control.Handle
int (or uint): A PInvoke can be setup to return an int
and it works just fine:
[DllImport("coredll.dll", SetLastError = true)]
public static extern int GetForegroundWindow();
private string GetActiveWindow()
{
const int nChars = 256;
int handle = 0;
StringBuilder Buff = new StringBuilder(nChars);
handle = CoreDLL.GetForegroundWindow();
if (CoreDLL.GetWindowText(handle, Buff, nChars) > 0)
{
return Buff.ToString();
}
return "";
}
So, int
vs IntPtr
? Does it matter for handles? Can you use either?
The IntPtr type can be used by languages that support pointers and as a common means of referring to data between languages that do and do not support pointers. IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System.
An IntPtr is an integer which is the same size as a pointer. You can use IntPtr to store a pointer value in a non-pointer type.
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.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With