• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1453
  • Last Modified:

Replacing objPtr in vb.net

Can I use this function in place or objPtr in vb.net. 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
        GC.Free()
        Return GC2
    End Function
0
bill_home
Asked:
bill_home
  • 3
  • 3
1 Solution
 
Todd GerbertIT ConsultantCommented:
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).

e.g.,

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
0
 
Todd GerbertIT ConsultantCommented:
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)

SomeWin32API(gc.AddrOfPinnedObject)

gc.Free
0
 
bill_homeAuthor Commented:
No sure what you solution code is for

Dim o As New SomeObject()  is...what any object...very confused now.
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
Todd GerbertIT ConsultantCommented:
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
        gch.Free()
    End Sub

End Module

Open in new window

0
 
bill_homeAuthor Commented:
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.

Bill
0
 
bill_homeAuthor Commented:
very helpful. Took the time to expand on his answer.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now