[英]how to declare function in vb.net to call c++ dll
I need to call a function located in a C++ dll from a VB.NET project.我需要从 ZBD5C8A1AFE53C83BA44F60C9Zdll 项目中调用 function
The definition in C++ dll documentation is: C++ dll 文档中的定义是:
HRESULT GetStatus(LPBYTE lpSize, LPBYTE lpStatus, HWND hWnd = 0)
lpSize
Data: size of lpStatus
lpSize
数据: lpStatus
的大小lpStatus
: Specify a pointer of an area to store the Device Status. lpStatus
:指定一个区域的指针来存储设备状态。
The Status and following data are stored.存储状态和后续数据。
255 bytes of space is required to store data存储数据需要 255 字节空间
I declare the function like this我这样声明 function
<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...但是当我打电话时,我收到一个关于 pinvoikeStackImbalance 的错误,pinvoke 签名不匹配......似乎定义不正确......
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: LPBYTE
通常会被声明为ByVal lpSize As Byte()
所以:
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.检查C++ function其实是StdCall,可能是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
.编辑查看您提供的少量信息,我非常怀疑lpSize
是否被声明为LPBYTE
,因为它表示lpStatus
中给出的数组的长度。 Also, hWnd
should be an IntPtr
此外, hWnd
应该是一个IntPtr
Here, it appears you are trying to receive a string in the space provided for in lpStatus
.在这里,您似乎正试图在lpStatus
提供的空间中接收一个字符串。 We can do this with Marshal.AllocHGlobal
, but an easier method using StringBuilder
is available.我们可以使用Marshal.AllocHGlobal
来做到这一点,但是使用StringBuilder
的更简单的方法是可用的。 Do NOT use String
for this:不要为此使用String
:
<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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.