Accessing Unmanaged Data (C++) from .NET

  • Thread starter Thread starter Frustrated
  • Start date Start date
F

Frustrated

Since C# and VB.NET are similar, I am posting this here also

I have a C++ DLL that I need to access from VB.NET or C#. The
following is my attempt via VB.NET.

The function I am trying to call is declared like this:

void* PASCAL iidc_lockdata( HIIDC, long frame = -1 )

This function returns a pointer to unsigned chars

I am able to find the size of the array out. It is usually 128800 to
use as an example if it helps.

I have declared the interface for my VB.NET as follows:

Private Declare Function _iidc_lockdata Lib "iidcapi_SONY.dll" Alias
"#37" (ByVal HIIDC As Int32, ByVal frame As Int32) As
System.Runtime.InteropServices.GCHandle

and also I have tried it as

Private Declare Function _iidc_lockdata Lib "iidcapi_SONY.dll" Alias
"#37" (ByVal HIIDC As Int32, ByVal frame As Int32) As IntPtr

(1) My first question is, how do I declare the function, should I use
GCHandle or IntPtr or something else?

As far as calling the function goes, I have tried this:

Dim gch As System.Runtime.InteropServices.GCHandle
gch = New System.Runtime.InteropServices.GCHandle
Dim lBufSz As Int32 = camera.currentDataFrameBytes(m_hCamera)
gch.Alloc(lBufSz)
Try
gch = camera.lockdata(m_hCamera, -1)
gch.Free()
Catch ex As Exception
MsgBox(ex.Message)
End Try

FYI the function camera.lockdata is a mapped function and it is as
follows:

Public Function lockdata(ByVal HIIDC As Int32, ByVal frame As Int32)
As System.Runtime.InteropServices.GCHandle
Return _iidc_lockdata(HIIDC, frame)
End Function


and I get "Object reference not set to an instance of an object"

(2) How would I get the data?

I have been really struggling with this.

Thanks,
Mike Dixon
 
Mike,

See inline:
void* PASCAL iidc_lockdata( HIIDC, long frame = -1 )

This function returns a pointer to unsigned chars

I am able to find the size of the array out. It is usually 128800 to
use as an example if it helps.

Unless the function has some sort of character sequence, then you won't
be able to. In other words, C++ doesn't know about the length of the block
of memory returned (well, in COM, it does, but that's a different story).

So, what functions usually do is they indicate that there is a sequence
in the memory indicating that it is the end of the block returned. You need
to do that here (find out what the block terminator is).
I have declared the interface for my VB.NET as follows:

Private Declare Function _iidc_lockdata Lib "iidcapi_SONY.dll" Alias
"#37" (ByVal HIIDC As Int32, ByVal frame As Int32) As
System.Runtime.InteropServices.GCHandle

and also I have tried it as

Private Declare Function _iidc_lockdata Lib "iidcapi_SONY.dll" Alias
"#37" (ByVal HIIDC As Int32, ByVal frame As Int32) As IntPtr

I would do it as the second one, with one change. Declare HIIDC as an
IntPtr. It looks like a handle to me. The frame parameter looks right.
You should also return an IntPtr. GCHandle is for managed constructs, not
unmanaged ones.
(1) My first question is, how do I declare the function, should I use
GCHandle or IntPtr or something else?

As far as calling the function goes, I have tried this:

Dim gch As System.Runtime.InteropServices.GCHandle
gch = New System.Runtime.InteropServices.GCHandle
Dim lBufSz As Int32 = camera.currentDataFrameBytes(m_hCamera)
gch.Alloc(lBufSz)
Try
gch = camera.lockdata(m_hCamera, -1)
gch.Free()
Catch ex As Exception
MsgBox(ex.Message)
End Try

FYI the function camera.lockdata is a mapped function and it is as
follows:

Public Function lockdata(ByVal HIIDC As Int32, ByVal frame As Int32)
As System.Runtime.InteropServices.GCHandle
Return _iidc_lockdata(HIIDC, frame)
End Function


and I get "Object reference not set to an instance of an object"

(2) How would I get the data?

Once you have that pointer in managed code, you are going to have to
cycle through the buffer, byte by byte, until you come across your
terminating sequence. Then you will know the length.

You have one other problem here. The memory was allocated and returned
to you. You need to pass that handle off eventually to another method to
free the memory allocated.

As a side note, this is a horrendously designed function. While some
people might not like the Windows API, it is brilliant in that it always
makes the managing of memory the responsibility of the user, unless the
rules of memory management are explicitly stated (as it is in COM).

Hope this helps.
 
Back
Top