我试图使用dllImport属性从vb(VS2013 Express)调用非托管dll,如下所示:
<DllImport("armdll32.dll", setlasterror:=True, charset:=CharSet.Ansi)>
Public Shared Function ArmConnect(ByVal port As Integer, ByVal baud As Long, ByRef serialNumber As String) As Integer
End Function
我正在调用这样的函数:
Dim serialNumber As String = ""
Debug.WriteLine(MicroScribeWrapper.ArmConnect(0, 0, serialNumber))
但是我收到以下错误:
托管调试助手'PInvokeStackImbalance'在'C:\ XXXX'中检测到问题 附加信息:调用PInvoke函数'MicroscribeSDKTest!MicroscribeSDKTest.MicroScribeWrapper :: ArmConnect'使堆栈失衡。这很可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配。
dll帮助文件中的文档描述了该功能,如下所示:
ArmConnect检测并建立与MicroScribe的连接。 ArmDll32 / ArmDll64将连接到它发现的第一个MicroScribe设备。检测顺序如下: 始终扫描所有USB端口; 如果使用port = 0和baud = 0调用,则扫描所有可用的串行(COM)端口并尝试连接115200波特;否则,以所需的波特率扫描所需的串行端口。 如果在USB端口上发现MicroScribe,则忽略端口号和波特率参数。使用USB连接时,有时需要将多个MicroScribe单元连接到主机。在这样的应用程序中,连接的每个唯一单元可以通过其序列号字符串来标识,由可选参数serialNumber传递。使用此配置时,需要为每个MicroScribe单元运行单独的ArmDLL实例。
int ArmConnect ( int port, long baud, char *serialNumber = 0 );
我很确定问题与我如何调用ArmConnect方法有关,但我尝试过的所有内容都失败了。
任何帮助都将不胜感激。
答案 0 :(得分:3)
我在这里可以看到一些问题。
long
为32位。因此,p / invoke中的baud
参数应为Integer
。 serialNumber
可能是C字符串。这是指向以null结尾的字符串的指针。这将是p / invoke中的ByVal serialNumber As String
。SetLastError
来返回错误。因此,总之,p / invoke应该是
<DllImport("armdll32.dll", CallingConvention=CallingConvention.Cdecl, _
CharSet:=CharSet.Ansi)>
Public Shared Function ArmConnect( _
ByVal port As Integer, _
ByVal baud As Integer, _
ByVal serialNumber As String _
) As Integer
End Function
或
<DllImport("armdll32.dll", CallingConvention=CallingConvention.Stdcall, _
CharSet:=CharSet.Ansi)>
Public Shared Function ArmConnect( _
ByVal port As Integer, _
ByVal baud As Integer, _
ByVal serialNumber As String _
) As Integer
End Function