I need to call a function located in a C++ dll from a VB.NET project.
The definition in C++ dll documentation is:
HRESULT GetStatus(LPBYTE lpSize, LPBYTE lpStatus, HWND hWnd = 0)
lpSize
Data: size of lpStatus
lpStatus
: Specify a pointer of an area to store the Device Status.
The Status and following data are stored.
255 bytes of space is required to store data
I declare the function like this
<DllImport("cplusplusdll.dll", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.StdCall, EntryPoint:="GetStatus")>
Public Function GetStatus(ByVal lpSize As String, ByRef lpStatus As String, ByVal hwnd As Long) As Integer
End Function
And I call it like this:
Dim status As String
result = GetStatus("255", status, 0)
but when I call, I get an error about pinvoikeStackImbalance, pinvoke signature not match... seems the definition is not ok...
I've tried lot of combinations but without success. Any help will be appreciated.
Thanks in advance.
LPBYTE
would normally be declared ByVal lpSize As Byte()
so:
Public Function GetStatus(ByVal lpSize As Byte(), ByRef lpStatus As Byte(), ByVal hwnd As Long) As Integer
Check the C++ function is actually StdCall, it may be CDecl.
EDIT
Looking at the small amount of info you provided, I very much doubt that lpSize
is declared LPBYTE
, as it represents the length of the array given in lpStatus
. Also, hWnd
should be an IntPtr
Here, it appears you are trying to receive a string in the space provided for in lpStatus
. We can do this with Marshal.AllocHGlobal
, but an easier method using StringBuilder
is available. Do NOT use String
for this:
<DllImport("cplusplusdll.dll", CharSet:=CharSet.Ansi, _
CallingConvention:=CallingConvention.StdCall, EntryPoint:="GetStatus")>
Public Function GetStatus(ByVal lpSize As Integer, <Out> ByVal lpStatus As StringBuilder, ByVal hwnd As IntPtr) As Integer
End Function
Dim status As New StringBuilder(255)
result = GetStatus(status.Length, status, 0)
```
We can also get the `HRESULT` marshaled directly to an exception, if you would like:
````vb
<DllImport("cplusplusdll.dll", CharSet:=CharSet.Ansi, _
CallingConvention:=CallingConvention.StdCall, EntryPoint:="GetStatus", _
PreserveSig = False)>
Public Sub GetStatus(ByVal lpSize As Integer, <Out> ByVal lpStatus As StringBuilder, ByVal hwnd As IntPtr)
End Sub