Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Related Posts
Laziness .NET -- the Professional Edition
Some new MSDN links of note
Visual Basic Resource Kit
Visual Basic Resource Kit Download Avail...
URLScan and the VB Resource Kit

Converting from an Integer to an IntPtr

Posted on March 3rd

A friend of mine at work just asked me this VB question, and it is an interesting one to me because it isn't as simple as it seems...

How do I cast from Integer to IntPtr?

In the end, I never really found an answer to that question, but I found out how to create a new IntPtr from an existing Integer and that seems close enough. You see, CType doesn't work because there isn't a defined conversion between the two types, and DirectCast only works with object references not value types like IntPtr. There isn't a System.Convert method for IntPtr to Int32... so what can you do? There is one option though, the constructor for IntPtr can accept an Int32 or a Int64 (Integer or Long in VB terms) and will assign the supplied value to the newly created IntPtr.

        Dim x As IntPtr
        Dim y As Integer = -1
        x = New IntPtr(y)

I never asked why there was a need to cast from Integer to IntPtr, but I'm assuming it is for some scenario where a handle/pointer is normally supplied or returned but -1 is used to indicate a special case...



Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

Well, it wouldn't make much sense to cast an integer to an IntPtr. Casting essentially means that a variable is really of a specific type, but the compiler doesn't know about it, so you tell it by casting. With casting, if the variable in question wasn't really of the type you cast it to, you have a problem. In .NET, the compiler goes to some lengths to find problems with this in advance, in contrast to C (for example) where it will just believe you whatever you say with a cast operator.

A conversion could obviously work, but it wouldn't do anything differently from your sample code. An IntPtr consists of two separate memory allocations: (a) The integer pointed to and (b) the pointer to said integer. So there's obviously no other choice than to construct the IntPtr if you need one. In your sample, the integer variable exists already, if you were to say

x = New IntPtr(5)

the two allocations I was talking about would actually take place at that point.

Another thing worth noting is this: often IntPtrs are used in conjunction with InterOp. There are many API functions you might want to use from .NET that pass in an IntPtr and expect you to put a return value into it. This stems from C, of course, from function signatures like "int myFunc(int * otherRetVal)". The pointer type is used as a reference type in this case and in C it's very easy to put a value into "the integer pointed to by the pointer": "*otherRetVal = 5;" will do the trick.

Now say you have the same thing in .NET, with a method signature (sorry, C#, VB is not my thing :-)) like "int myFunc(IntPtr otherRetVal)". Putting the otherRetVal into the integer pointed to seems tricky now, because you can't directly write to the pointer. Also, you can't simply construct another pointer, because the parameter is not a ref or out parameter. The way to do this is to use a method of the Marshal class:

Marshal.WriteInt32(otherRetVal, 5);

Have fun!

If you use PInvoke at all, you will often need to compare IntPtr to Int32...

Forgive me if this is an ignorant comment, but can't you do:

[code]Dim x as IntPtr
Dim y as Integer = 1337
x = IntPtr (y)[/code]

without the new? I don't do VB .NET at all, but the equivelant in C++/CLI works fine.

No, it works only in C# In VB.NET it is done the following way:

Dim x as IntPtr
Dim y as Integer = 1337
x = IntPtr.op_Explicit(y)

Thanks very much. It works nice!

Hi
I am facing a problem in C#. I followed one example in the redbook OpenGL book. However, it makes the following error:

Error 1:
The best overloaded method match for 'CsGL.OpenGL.GL.glDrawElements(uint, int, uint, System.IntPtr)' has some invalid arguments.
Error 2:
Argument '4': cannot convert from 'int[]' to 'System.IntPtr'.

I have defined the variable and the function as follows:

private static int[] vertices = {
25, 25,
100, 325,
175, 25,
175, 325,
250, 25,
325, 325
};

GL.glDrawElements(GL.GL_POLYGON, 4, GL.GL_UNSIGNED_INT, vertices)

I would be grateful if you help me in this regard.