2016-05-13 49 views
-1

我有一個(C/C++)DLL,我通過DLLImport調用到C#項目。 這個DLL有以下方法:從非託管代碼傳遞指針與出修飾符

int __stdcall Connect(OUT int *p_sessionID, IN BYTE mode, IN BYTE comport, IN char *servername, IN DWORD serverport); 

我嘗試了幾種方法來「翻譯」它的C#,而是一個我覺得是接近的是:

[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect", CallingConvention = CallingConvention.StdCall)] 
private static extern unsafe int CS1_Connect(out IntPtr p_sessionID, byte mode, byte comport, string servername, int serverport); 

我試圖調用是這樣的:

IntPtr connection; 
var i = Connect(out connection, 1, 0, "192.0.0.1", 1982); 

但我一直得到以下錯誤:

其他信息:1個電話到PInvoke函數'DllImportTest!DllImportTest.Program :: Connect'已經失去了堆棧。這很可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配。檢查PInvoke簽名的調用約定和參數是否與目標非託管簽名相匹配。

我知道我可以到達DLL,因爲我有另一種方法工作正常。

我在做什麼錯?

謝謝。

+0

第一個參數應該是'out int'。但是這並不能解釋MDA警告,你必須假定函數的文檔已經過時了。沒有其他的方式來檢查,所有的裝飾已被刪除。您必須聯繫圖書館作者尋求支持。 –

+0

它會解釋MDA,如果目標是64位 –

+0

不是真的,IntPtr也會增長,前4個參數會通過寄存器而不是堆棧。 –

回答

0

您的第一個參數翻譯不正確。

OUT int *p_sessionID 

這裏OUT是一個向讀者指出語義的宏。宏將其擴展至無。等前處理後,你有:

int *p_sessionID 

這轉化爲

out int sessionID 
在C#

你不需要聲明函數爲不安全的,刪除它。最後的參數是無符號的。您可能需要切換至uint

正確的翻譯將因此會:

[DllImport("UnmanagedDLL.dll", EntryPoint = "Connect", 
    CallingConvention = CallingConvention.StdCall)] 
private static extern int CS1_Connect(
    out int sessionID, 
    byte mode, 
    byte comport, 
    string servername, 
    uint serverport 
); 

如果仍然收到堆棧不平衡的消息,那麼你就會知道,非託管函數沒有你在問題中所引述的簽名。

+0

我已經試過了。但我得到了同樣的錯誤。如果我不使用不安全,我不能編譯代碼。 最後一個參數是uint。我在這裏打字時想念拼寫。 –

+0

這不是一個試驗和錯誤的遊戲。那不是要走的路。如果我的答案中的函數導致堆棧不平衡警告,那麼您知道您所擁有的C函數聲明與實際函數不匹配。 –

+0

好的。感謝您的幫助! –

相關問題