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 から取得した関数ポインターでは使用できません。このメソッドを使用して、関数ポインターから別のマネージ デリゲートへのデリゲートを作成することはできません。

これができない理由はわかりませんが、Microsoft の共通言語ランタイムは FastCall 呼び出し規約を使用しているが、 FastCall はPInvokeではサポートされていないためだと思います。

于 2012-05-23T16:34:21.870 に答える