Arun R
Arun R

Reputation: 33

VB.NET Address Pointer

I have a DLL with the following function and is being used in my application

WritetoBuffer(BYTE* pBuffer, DATA_TYPE Type);

This is the code being used in VB 6

Dim pBuffer() as byte
ReDim pBuffer(0 To (300 * 400 * 3 - 1))
Dim ppBuf As Long
ppBuf = VarPtr(pImageBuffer(0))                                             
Dim Rtn As Integer
Rtn = WritetoBuffer(ppBuf, 1)           

I am trying to write the equivalent code in VB.NET, but I am facing difficulties in it. Tried using the following function, but it's not working.

 Public Function VarPtr(ByVal e As Object) As Intptr
        Dim GC As GCHandle = GCHandle.Alloc(e, GCHandleType.Pinned)
        Dim GC2 As Intptr = GC.AddrOfPinnedObject.ToInt32
        GC.Free()
        Return GC2
    End Function

I haven't used Marshal Class or similar functions before and I am not sure about the right way to do it. Can someone please advice me on this?

Upvotes: 1

Views: 1901

Answers (3)

Chillzy
Chillzy

Reputation: 468

Try this. You need GCHandle to stay alive while you make your call. Just returning the address of the pointer is not enough from what I understand. When you're done then free the handle.

Dim Handle As GCHandle = GCHandle.Alloc(pBuffer, GCHandleType.Pinned)
Dim ppbuf As IntPtr = Handle.AddrOfPinnedObject.ToInt32
Dim Rtn As Integer
Rtn = WritetoBuffer(ppbuf, 1)
Handle.Free()

Upvotes: 0

Visual Vincent
Visual Vincent

Reputation: 18310

In cases such as this you shouldn't need to get a pointer of your byte array. Due to the fact that since BYTE* pBuffer is used as an array, that is all you need it to be in VB.NET as well.

Thus you could declare your P/Invoke like this:

<DllImport("yourfile.dll")> _
Public Shared Function WritetoBuffer(ByVal pBuffer As Byte(), ByVal Type As Integer) As Integer
End Function

...and then use it like this:

Dim pBuffer() as byte
ReDim pBuffer(0 To (300 * 400 * 3 - 1))

Dim Rtn As Integer = WritetoBuffer(pBuffer, 1)

Upvotes: -1

Ry-
Ry-

Reputation: 224942

As @Dai commented, .ToInt32 is incorrect here, and you can’t free the handle before you use it.

Dim pBuffer(300 * 400 * 3 - 1) As Byte
Dim pinned = GCHandle.Alloc(pBuffer, GCHandleType.Pinned)
Dim Rtn As Integer = WritetoBuffer(pinned.AddrOfPinnedObject(), 1)
pinned.Free()

Upvotes: 2

Related Questions