2

为了模拟来自 C++ 的调用,我正在尝试以下代码

    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() 然后调用返回的委托。

谢谢。

4

1 回答 1

3

您不能使用 GetDelegateForFunctionPointer() 来获取托管函数的委托。这是来自MSDN

您不能将无效的函数指针传递给 GetDelegateForFunctionPointer。此外,您只能将此方法用于纯非托管函数指针。您不能将此方法用于通过 C++ 或从 GetFunctionPointer 获得的函数指针。您不能使用此方法创建从函数指针到另一个托管委托的委托。

我不确定你为什么不能这样做,但我想这是因为微软的公共语言运行时使用 FastCall 调用约定,但PInvoke不支持 FastCall

于 2012-05-23T16:34:21.870 回答