Replacing objPtr in

Posted on 2009-12-16
Last Modified: 2012-05-08
Can I use this function in place or objPtr in I used it for VarPtr (vb6) and is works fine. Not sure if it will work for objPtr

 Public Function VarPtr(ByVal e As Object) As Integer
        Dim GC As System.Runtime.InteropServices.GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)

        Dim GC2 As Integer = GC.AddrOfPinnedObject.ToInt32
        Return GC2
    End Function
Question by:bill_home
    LVL 33

    Expert Comment

    by:Todd Gerbert
    I may be mistaken, but I was under the impression that the value returned by GCHandle.AddrOfPinnedObject is no longer guaranteed to be valid after the GCHandle has been freed (because the .Net runtime may move the object after it's no longer pinned).


    Dim o As New SomeObject()
    Dim gc As GCHandle = GCHandle.Alloc(o, Type.Pinned)
    Dim address As Int32 = gc.AddrOfPinnedObject.ToInt32
    gc.Free    'o is no longer pinned, Common Language Runtime Garbage Collector is free to move it
    'Garbage Collector moves o
    SomeWin32API(address) 'Error
    LVL 33

    Expert Comment

    by:Todd Gerbert
    So the point is don't do it quite that way... ;)

    <DllImport("library.dll")> _
    Public Declare Sub SomeWin32API(ByVal AddressOfObject As IntPtr)

    Dim o As New SomeObject()
    Dim gc As GCHandle = GCHandle.Alloc(o, Pinned)



    Author Comment

    No sure what you solution code is for

    Dim o As New SomeObject()  is...what any object...very confused now.
    LVL 33

    Accepted Solution

    It's whatever, any object - just used it for the sake of the example, like a "widget." ;)

    The point is that

    1) Once you call GCHandle.Free, whatever value you obtained from GCHandle.AddrOfPinnedObject should no longer be considered valid. You would call GCHandle.Alloc, make use of GCHandle.AddrOfPinnedObject, and then when you no longer need the address call GCHandle.Free.

    2) Presumably you want the address in order to pass it to a Windows API which is expecting a pointer to an object. When declaring the Windows API function you should use IntPtr's instead of Int32's - on a 64-bit system (which is increasingly common) Windows is going to expect a pointer to an object to be 64-bits, or an Int64, and you'll likely get unpredictable results if you only give it an Int32.

    Consider this sample which uses the Windows MessageBox API instead of the regular MsgBox just for examples sake.  The second parameter in the API is an address to the string, so I delcared it as an IntPtr (ByVal lpText As IntPtr).  
    Imports System.Runtime.InteropServices
    Module Module1
        <DllImport("user32.dll", EntryPoint:="MessageBox")> _
        Public Function MyMessageBox(ByVal hWnd As IntPtr, ByVal lpText As IntPtr, ByVal lpCaption As String, ByVal uType As UShort) As Int32
        End Function
        Sub Main()
            Dim messageBytes() As Byte
            'Create an array of bytes containing the letters to form the string "Hello World"
            messageBytes = System.Text.Encoding.ASCII.GetBytes("Hello World")
            'Add a NULL character to the end
            ReDim Preserve messageBytes(12)
            messageBytes(12) = 0
            Dim gch As GCHandle = GCHandle.Alloc(messageBytes, GCHandleType.Pinned)
            'This is used specifically because it's a pinned array, for any other object type you'd
            'use gch.AddrOfPinnedObject()
            Dim addressOfString As IntPtr = Marshal.UnsafeAddrOfPinnedArrayElement(messageBytes, 0)
            'Now that we have an IntPtr, thanks to pinning our array with a GCHandle, now we can pass it to the Windows API
            MyMessageBox(IntPtr.Zero, gch.AddrOfPinnedObject(), "Title", 0)
            'Now we're done, the GCHandle can be freed
        End Sub
    End Module

    Open in new window


    Author Comment

    thanks Tbgert. I have to move to another fire. I will get back to this and test. I have not forgotten and will not leave it hanging.


    Author Closing Comment

    very helpful. Took the time to expand on his answer.

    Featured Post

    Do You Know the 4 Main Threat Actor Types?

    Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

    Join & Write a Comment

    When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
    Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
    As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
    This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

    734 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    23 Experts available now in Live!

    Get 1:1 Help Now