[英]Solution to PInvokeStackImbalance exception (Calling unmanaged C++ dll from C#) - VS2010
我一整天都在解決這個問題,我不希望其他人也必須這樣做。 因此,這既是問題,也是解決方案:
問題 :嘗試在C#代碼中的C ++ dll中使用方法時,會收到PInvokeStackImbalance異常。 這是您在示例中看到的典型聲明...
例子不起作用
(C++ .h file)
extern "C" {
__declspec(dllexport) int Addints(int a, int b);
}
(C++ .cpp file)
extern int Addints(int a, int b) {
return a+b;
}
(C# .cs file)
[DllImport("testdll.dll")]
static extern int Addints(int a, int b);
static void Main(string[] args)
{
Console.WriteLine("Hello world lets add some stuff");
Int32 a = 3;
Int32 b = 5;
Console.WriteLine(Addints(a,b));
}
當您運行此程序時,它會抱怨您已使堆棧不平衡(不高興!),您實際上不應該繼續。 它還說您應該檢查方法的簽名以確保它們匹配。
撒謊。
修復 :您需要做的是在您的DLLImport語句中添加一個小東西,如下所示:
這是修復
[DllImport("testdll.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int Addints(int a, int b);
是的,那CallingConvention的東西? Reeeeeeeeeealy很重要。
其他一些技巧:
-確保為同一目標同時構建dll和C#exe。 分別是Win32和x86
-確保您的dll是使用/ clr選項構建的(項目屬性-配置屬性-常規)
-請注意,邊界另一側的C ++ int,float,string大小可能不相同(請在此處查看類型如何匹配)
-要獲得一個非常好的分步示例,請查看程序員notebook.wordpress.com/2010/01/18/calling-a-cpp-dll-from-cs
棚子
我不願意這樣做,但您的答案並非全部。 默認情況下,C / C ++使用Cdecl調用約定,因此顯而易見,必須進行貼花的原因很明顯。
真正的解決方案只是在C ++代碼中聲明調用約定。
http://msdn.microsoft.com/zh-CN/library/zxk0tw93(v=VS.100).aspx
還有其他調用約定http://msdn.microsoft.com/zh-cn/library/984x0h58.aspx,因此您的答案實際上取決於C / C ++非托管代碼的調用約定。
我懷疑VS2008與.NET Framework 3.5有更多關系的原因。
只需將函數更改為此:
__declspec(dllexport) int __stdcall Addints(int a, int b);
簡潔版本:
確保C#中的DllImport語句包含設置為CallingConvention.Cdecl的CallingConvention參數
詳情請見上文
是的,這很可愛。 但是,它也有效-仔細閱讀我寫的內容,我說這是對“您在示例中看到的典型聲明”的修復。 您可能會問什么例子? 好吧,這里有幾個:
dotnetperls.com/dllimport
程序員notebook.wordpress.com/2010/01/18/calling-a-cpp-dll-from-cs/
blogs.msdn.com/b/jonathanswift/archive/2006/10/02/780637.aspx
msdn.microsoft.com/zh-CN/library/aa984739(VS.71).aspx
msdn.microsoft.com/zh-CN/library/26thfadc.aspx
www.codeguru.com/columns/kate/article.php/c3947
www.apachetechnology.net/KC/NativeDLL2Net.aspx
到目前為止,我還沒有看到這種變體。 但是,如果它們都起作用,那么哪里有問題呢? 如果您需要榮譽,那么您可以:太棒了! 贊! 現在人們有兩種選擇。 哦,順便說一句,您的“答案不是全部答案”:
(C++ .h) extern "C" {
__declspec(dllexport) int __stdcall Addints(int a, int b); }
(C++ .cpp) int __stdcall Addints(int a, int b) {
return a+b; }
您還需要更改cpp文件。
再次-我使用的是.Net 4的VS2010(不知道您所說的是關於VS2008的評論)。
抱歉,較早的鏈接斷開可以在這里找到平台調用數據類型:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.