2014-07-07 69 views
-2

我試圖調用從VB的非託管的DLL(VS2013快遞)使用DllImport屬性如下:DllImport屬性PInvokeStackImbalance錯誤

<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端口; 如果使用端口= 0和波特= 0調用,則掃描所有可用的串行(COM)端口並嘗試連接115200波特;否則,以所需的波特率掃描所需的串行端口。 如果在USB端口上發現MicroScribe,則會忽略端口號和波特率參數。使用USB連接時,有時需要將多臺MicroScribe設備連接到主機。在應用程序中,每個連接的唯一單元可以通過序列號字符串進行標識,並由可選參數serialNumber傳遞。使用此配置時,需要爲每個MicroScribe單元運行ArmDLL的單獨實例。

 int ArmConnect (int port, long baud, char *serialNumber = 0); 

我敢肯定,這個問題與我如何調用該方法ArmConnect但一切我試過至今沒有做到。

任何幫助,將不勝感激。

+1

'的ByRef SERIALNUMBER作爲String'與替換''ByVal'波特率作爲Long'替換' Integer' –

+0

也確保CallingConvention:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.callingconvention(v=vs.71).aspx –

回答

2

我可以在這裏看到一些問題。

  • 在Windows上的C++中,long是32位。所以p/invoke中的baud參數應該是Integer
  • 字符串參數serialNumber可能是一個C字符串。這是指向以空字符結尾的字符串。這將是p/invoke中的ByVal serialNumber As String
  • 最後是調用約定。正如所寫的,看起來非託管代碼使用cdecl調用約定。你的p/invoke使用stdcall。我猜想,非託管代碼的調用約定實際上是stdcall,並且你所包含的文檔忽略了這一點。閱讀該庫的頭文件將清除該頭文件。
  • 我認爲函數不可能通過調用SetLastError來返回錯誤。

因此,簡言之,在p /調用應該是

<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 
+0

謝謝大衛。按照您的建議查看頭文件,結果發現有ArmConnectSN以及ArmConnect。第一個使用serialNumber參數,第二個不使用。結合你的其他建議,看起來有些事情可行。再次感謝! – user3812297

+0

是的。對於那個很抱歉。這是我的第一個問題,我不知道我需要如何關閉它。 – user3812297

+0

沒關係。感謝你的接納。 –