Share via


PInvokes - int to IntPtr

Question

Monday, July 14, 2008 11:28 PM

Hi,
I'm fairly new to the world of PInvokes and I just want to make sure I've got some of the basics right! Firstly am I right in assuming you should always try and use IntPtr values when passing to PInvokes so it will work on 32bit and 64 bit? Secondly I want to know how to convert an int to IntPtr.

Basically I'm using Spy++ to look at messages being passed to a window. I notice that (IntPtr)0x00000001 is being passed in and this equals 184 some how (mouse button press x-coord)? and (IntPtr)0x006300B8 is 99... I just need to know how to convert random ints into these types of 8 bit numbers.

Any help or pointers on this matter will be greatly appreciated.
Thanks.

All replies (8)

Monday, July 14, 2008 11:47 PM ✅Answered | 1 vote

> Firstly am I right in assuming you should always try and use IntPtr values when passing to PInvokes so it will work on 32bit and 64 bit?

Use IntPtr when the API is documented to use a pointer type.  Not all int should be IntPtr.  For example, if you see INT in the API documentation, you should use int so that it is 32 bits on all platforms.

The PInvoke Interop Assistant is highly useful for getting these signatures correct:  http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120

> Secondly I want to know how to convert an int to IntPtr.

            int x = 10;  
            IntPtr xAsIntPtr = new IntPtr(x); 

Tuesday, July 15, 2008 12:40 AM ✅Answered

 MSDN Says:

The IntPtr type is designed to be an integer whose size is platform-specific. That is, an instance of this type is expected to be 32-bits on 32-bit hardware and operating systems, and 64-bits on 64-bit hardware and operating systems.

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.IO.FileStream class to hold file handles.

The IntPtr type is CLS-compliant, while the UIntPtr type is not. Only the IntPtr type is used in the common language runtime. The UIntPtr type is provided mostly to maintain architectural symmetry with the IntPtr type.

This type implements the ISerializable interface.


AlexB


Tuesday, July 15, 2008 12:25 PM ✅Answered

** wParam and lParam are basically one big 16 bit flag
**
You map them to .NET as Int16. Then you can convert them to byte array and do manipulations on your two bytes or use BitArray class to accomplish what you want.


AlexB


Tuesday, July 15, 2008 12:01 PM

Hi,
Firstly thanks for your replies! I don't know why I didn't think about using the constructor! One thing still confuses me - when I put in the values I mentioned on the original post - they dont come out like they do in Spy++ (im doing new IntPtr(184).ToString("x8")) - it's giving values that are close but not exactly the same. Can anyone shed any light on why this would be different?
Thanks.

[Edit]Actually I might be slightly off - I need to convert x and y positions into the wParam and lParam parameters for a sendmessage. These are both IntPtr types (as suggested by PInvoke site), but I've just clicked on position 144,144 and the values posted are 00000001 and 00900090 -> so it's looking like the params are not just the x and y position. Again, if anyone can shed light on this that would be great.[/Edit]


Tuesday, July 15, 2008 12:15 PM

Right - think I might have it... the wParam and lParam are basically one big 16 bit flag. Each number can be up to 8 bits, but for my example (i.e. 144 and 144) they are combined into one 8 bit flag (00900090, which is 144 followed by 144). Can anyone explain when you 'overflow' into the second parameter?


Friday, April 23, 2010 12:41 PM

What's the difference if I should write i.e.

 

IntPtr xAsIntPtr = (IntPtr)x;

 

instead of

 

IntPtr xAsIntPtr = new  IntPtr(x);


Saturday, April 24, 2010 1:50 AM

The cast syntax invokes the explicit conversion operator which will in turn will call the constructor.  Thus, it potentially runs a little more code, but this difference might be inlined/optimized away by the JIT.  You should use the syntax that you prefer.


Wednesday, January 26, 2011 9:09 PM

** wParam and lParam are basically one big 16 bit flag
**
You map them to .NET as Int16. Then you can convert them to byte array and do manipulations on your two bytes or use BitArray class to accomplish what you want.


AlexB

I'm pretty sure wParam is a 32 bit integer and lParam is a pointer, so it will be Int32 and a IntPtr.dm