2012-05-23 19 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。