Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net DLLImport属性PINVOKESSTACK不平衡错误_.net_Pinvoke_Dllimport - Fatal编程技术网

.net DLLImport属性PINVOKESSTACK不平衡错误

.net DLLImport属性PINVOKESSTACK不平衡错误,.net,pinvoke,dllimport,.net,Pinvoke,Dllimport,我正在尝试使用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

我正在尝试使用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
但我得到了以下错误:

托管调试助手“PinvokeStackDistancement”在“C:\XXXX”中检测到问题 附加信息:调用PInvoke函数“microscriesdktest!”!MicroscribeSDKTest.MicroScribeWrapper::ArmConnect'使堆栈不平衡。这可能是因为托管PInvoke签名与非托管目标签名不匹配。检查PInvoke签名的调用约定和参数是否与目标非托管签名匹配

dll帮助文件中的文档对函数的描述如下:

ArmConnect检测并建立到微型屏幕的连接。ArmDll32/ArmDll64将连接到它发现的第一个微型屏幕设备。检测顺序如下: 始终扫描所有USB端口; 如果使用端口=0和波特率=0调用,扫描所有可用的串行(COM)端口,并尝试以115200波特率连接;否则,以所需波特率扫描所需串行端口。 如果在USB端口上发现微型脚本,则忽略端口号和波特率参数。当使用USB连接时,有时需要将多个微型筛单元连接到主机。在这样的应用程序中,可以通过可选参数serialNumber传递的序列号字符串来标识连接的每个唯一单元。使用此配置时,需要为每个MicroScribe单元运行单独的ArmDLL实例

我很确定这个问题与我如何调用ArmConnect方法有关,但我尝试过的一切都失败了


任何帮助都将不胜感激。

我可以在这里看到一些问题

  • Windows上的C++,代码>长为32位。因此p/invoke中的
    baud
    参数应该是
    Integer
  • 字符串参数
    serialNumber
    可能是一个C字符串。这是指向以null结尾的字符串的指针。这将是p/invoke中作为字符串的
    ByVal serialNumber
  • 最后是呼叫约定。如前所述,非托管代码似乎使用cdecl调用约定。您的p/invoke使用stdcall。我假设非托管代码的调用约定实际上是stdcall,您包含的文档可能会忽略这一点。读取库的头文件可以清除这些信息
  • 我认为函数不太可能通过调用
    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

公共共享功能ArmConnect(_
ByVal端口为整数_
ByVal baud作为整数_
ByVal serialNumber作为字符串_
)作为整数
端函数


公共共享功能ArmConnect(_
ByVal端口为整数_
ByVal baud作为整数_
ByVal serialNumber作为字符串_
)作为整数
端函数

ByRef serialNumber As String
替换为
ByVal
baud As Long
替换为
Integer
也确保调用约定:谢谢David。我按照您的建议查看了头文件,结果发现有一个ArmConnectSN和ArmConnect。第一个使用serialNumber参数,第二个不使用。这一点,再加上你的其他建议,似乎已经起到了作用。再次感谢!对很抱歉。这是我的第一个问题,我没有意识到我需要如何结束它。
        int ArmConnect ( int port, long baud, char *serialNumber = 0 );
<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