Converting from an Integer to an IntPtr

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…

Converting from an Integer to an IntPtr

7 Responses

  1. 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!

    Oliver Sturm March 4, 2005 at 11:09 am #
  2. If you use PInvoke at all, you will often need to compare IntPtr to Int32…

    C Stewart March 15, 2006 at 7:26 pm #
  3. 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.

    Todd Aspeotis April 25, 2006 at 9:20 am #
  4. 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)

    Slowmo July 29, 2006 at 11:37 pm #
  5. Thanks very much. It works nice!

    Rupesh February 6, 2007 at 7:39 am #
  6. 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.

    mahtab October 2, 2007 at 6:49 pm #
  7. One scenario where this was useful to me was accessing the Windows Native API to query process information – The NtQueryInformationProcess API call returns (amongst other thing) a pointer to the first element of variable-length Array(ULong).

    This is complex to handle well in VB.Net so it’s easier to just access the memory directly. Since we know the size of a ULong for the current architecture, we can determine the address of any element by index.

    We then need to convert the calculated address into a pointer to the desired element before we can retrieve it.

    Simon April 12, 2012 at 5:30 am #

Leave a Reply