要模拟来自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()然后调用返回的委托。
感谢。
答案 0 :(得分:3)
您不能使用GetDelegateForFunctionPointer()来获取托管函数的委托。这来自MSDN:
您无法将无效的函数指针传递给 GetDelegateForFunctionPointer。此外,您只能使用此功能 纯非托管函数指针的方法。你不能用这个 具有通过C ++或从中获得的函数指针的方法 GetFunctionPointer。您不能使用此方法来创建委托 从函数指针到另一个托管委托。
我不确定为什么你不能这样做,但我想这是因为微软的Common Language Runtime使用FastCall调用约定,但FastCall is not supported用于PInvoke。