簡體   English   中英

PInvokeStackImbalance異常的解決方案(從C#調用非托管C ++ dll)-VS2010

[英]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的評論)。

抱歉,較早的鏈接斷開可以在這里找到平台調用數據類型:

http://msdn.microsoft.com/en-us/library/ac7ay120.aspx

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM