简体   繁体   English

如何在 vb.net 中声明 function 以调用 c++ Z06416233FE5EC4C591ZAFAF28

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM