我有供應商的API調用,我想在我的C#Windows Forms應用程序中使用它。問題是無論我嘗試什麼P/Invoke,我都會在線路上發生崩潰,說明該通話不平衡。我嘗試過與供應商合作,但他們沒有Visual Studio 2012,也沒有任何C#或.NET的經驗,並且經過幾次來回電子郵件後,他們基本上都解決了問題。在C#中與C/C++例程接口導致翻譯
這裏是他們的官方C/C++聲明
const char *<dll name here>(int Param1,
const char *Param2,
const char *Param3,
unsigned long Param4,
unsigned short Param5,
unsigned short Param6,
unsigned short Param7,
unsigned short Param8,
unsigned short Param9);
這裏是最近的P/Invoke的DllImport行我試過了。
[System.Runtime.InteropServices.DllImport(
"<dll name here>", EntryPoint = "<AnsiFunctionName>", ExactSpelling = true,
CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
public static extern String <AnsiFunctionName>(int Param1,
String Param2,
String Param3,
ulong Param4,
Int16 Param5,
Int16 Param6,
Int16 Param7,
Int16 Param8,
Int16 Param9);
下面是實際的錯誤消息:
主題行:PInvokeStackImbalance檢測
到P A呼叫/調用功能 '' 具有不平衡堆棧。這很可能是因爲託管的PInvoke簽名與非託管目標籤名不匹配。檢查P/Invoke簽名的調用約定和參數是否與目標非託管簽名相匹配。
我嘗試了各種各樣的東西,甚至把一個void返回類型。我試過不使用返回類型。我嘗試了而不是Strings,StringBuilders和IntPtrs。不管我嘗試過什麼,沒有任何工作。
我在閱讀堆棧上的文章後提到供應商 溢出返回字符串是危險的,不應該這樣做。他們的反應是:
「該網頁上提到的字符串返回問題並不適用於 我們的函數它們返回一個指向靜態分配的字符串,這樣你就不會需要釋放它(。絕不能試圖這樣做),它看起來像「UnmanagedType.LPStr」應該工作(雖然IntPtr的事情應該工作過,用適當的轉換或鑄造)
更新#1:如前所述在評論中,我使用uint,而不是ulong,直到這篇文章,我只是認爲我會比較好看,uint和ulong都不起作用
更新#2:也許給實際的函數名稱將有所幫助。它是犰狳CreateCodeShort3A。展望未來,我正在使用純.NET,但我仍然需要與之交互,但目前尚不可能。更重要的是,這個問題讓我很好奇,爲什麼我無法解決像P/Invoke這樣看似簡單的事情。畢竟,那裏有多少變化? (不是一個嚴肅的問題)。
這可能不是主要的問題,而是「無符號長」在C++中通常會等同於「UINT」在C#中,不「ULONG」。 (同樣,C++中的「long」通常是C#中的「int」)。另一方面,「unsigned long long」將等同於C#中的「ulong」。 –
直到這篇文章,我使用uint,而不是ulong,只是爲了寫這個問題,我把它改爲ulong,這也失敗了。我嘗試了數十億次,或者至少有不少排列,至今沒有任何效果。 –
您忘記了調用約定 - 您需要'CallingConvention = CallingConvention.Cdecl'作爲DllImport的一部分,否則它使用StdCall調用約定,這是不正確的並導致此錯誤 – Petesh