2012-05-23 21 views
2

爲了模擬從C++調用,我想下面的代碼獲得委託的IntPtr的和調用

private delegate void CppFuncDelegate(string message); 

    private static void Main(string[] args) 
    { 
     Console.WriteLine("+++ BEGIN TEST +++"); 

     Action<string> action = str => Console.WriteLine("Received:" + str); 
     IntPtr delegatePtr = action.Method.MethodHandle.GetFunctionPointer(); 

     CppFuncDelegate cppFuncDelegate = (CppFuncDelegate) 
      Marshal.GetDelegateForFunctionPointer(delegatePtr, 
                 typeof(CppFuncDelegate)); 
     cppFuncDelegate.Invoke("Hello"); 
    } 

,但我得到

檢測PInvokeStackImbalance。 對PInvoke函數'Test!Test.Program + CppFuncDelegate :: Invoke' 的調用已使堆棧不平衡。這很可能是因爲託管PInvoke 簽名與非託管目標籤名不匹配。檢查 PInvoke簽名的調用約定和參數是否匹配 目標非託管簽名。

誰能告訴我什麼,我做錯了什麼?

注意:請不要告訴我做action.Invoke();這不是這個練習的重點。我想讓IntPtr處理委託並使用GetDelegateForFunctionPointer(),然後調用返回的委託。

謝謝。

+0

您是否檢查過PInvoke簽名的調用約定是否與目標非受控簽名匹配? – dtb

+0

@dtb'CppFuncDelegate'接受一個字符串並返回void,並且我將action的委託聲明爲'Action ';所以我認爲他們匹配。有沒有其他方法來檢查PInvoke簽名? –

+0

我不想談論參數,我正在談論調用約定。 – dtb

回答

3

不能使用GetDelegateForFunctionPointer()來獲取管理功能的代表。這是MSDN

可以無效的函數指針不傳遞給 GetDelegateForFunctionPointer。另外,你只能使用這個 方法來完成非託管函數指針。對於通過C++或 GetFunctionPointer獲取的函數指針,您不能使用此 方法。您不能使用此方法從函數指針創建委託 到另一個託管代理。

我不知道爲什麼你不能做到這一點,但我想這是因爲微軟的公共語言運行時使用快速調用調用約定,但對於FastCall is not supported的PInvoke。