2010-03-12 54 views
3

這裏是C++ DLL的代碼:C++ dll的C#包裝器; 「運行時檢查失敗#0 - 在函數調用中未正確保存ESP的值。」錯誤

extern "C" _declspec(dllexport) int testDelegate(int (*addFunction)(int, int), int a, int b) 
{ 
    int res = addFunction(a, b); 
    return res; 
} 

,這裏是在C#代碼:

public delegate int AddIntegersDelegate(int number1, int number2); 

public static int AddIntegers(int a, int b) 
{ 
    return a + b; 
} 

[DllImport("tester.dll", SetLastError = true)] 
public static extern int testDelegate(AddIntegersDelegate callBackProc, int a, int b); 

public static void Main(string[] args) 
{ 
    int result = testDelegate(AddIntegers, 4, 5); 
    Console.WriteLine("Code returned:" + result.ToString()); 
} 

當我開始這個小應用程序,我從這個帖子的標題得到的消息。有人可以幫忙嗎?

由於提前,

d

回答

11

亞當是正確的,你已經上了通話功能的不匹配約定在32位版本的Windows上。函數指針默認爲__cdecl,委託聲明默認爲CallingConvention.StdCall。不匹配會導致堆棧指針在委託調用返回時無法正確恢復,從而觸發C/C++代碼的調試版本中的診斷。

要修復它在C/C++方面:

typedef int (__stdcall * Callback)(int, int); 

extern "C" _declspec(dllexport) int testDelegate(Callback addFunction, int a, int b) 
{ 
    int res = addFunction(a, b); 
    return res; 
} 

要修復它在C#的一面:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
    public delegate int AddIntegersDelegate(int number1, int number2); 
+1

啊,upvoting你的答案'CallingConvention.Cdecl',因爲我是完全不知道這一點。 – 2010-03-13 10:36:48

+0

夥計們,非常感謝你。你已經解決了我的問題。 – 2010-03-15 07:21:29

+1

雖然,這適用於我,而不是 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate int AddIntegersDelegate(int number1,int number2); 我把: [UnmanagedFunctionPointer(CallingConvention.StdCall)] public delegate int AddIntegersDelegate(int number1,int number2); – 2010-03-15 10:04:04

0

它通常意味着一個「接口不匹配」:用於編譯所述客戶端聲明來自DLL的實際版本不同。

3

testDelegate函數指針參數需要被打上__stdcall,否則調用它會破壞堆棧(因爲它使用不同的調用約定。)

相關問題