2

アンマネージ コードからマネージ メソッドを呼び出そうとしています。ただし、マネージド コードでは '(__clrcall) 呼び出し規約を使用する必要があり、アンマネージド C++ コードでは、/clr オプションを使用せずに __clrcall 呼び出し規約を使用することを拒否しています。管理されていないプロジェクトは管理されているプロジェクトに変更するものではないため、私はそれをやりたいとは思いません。

CodeGuru と MSDN で見たように、マネージ側でこれらすべてのデリゲートと関数ポインターのマーシャリングを作成しましたが、ref クラスのメンバーになれない __stdcall 規則を使用して静的関数を呼び出さない限り、このエラーは引き続き表示されます。メソッドは、ref クラスのインスタンスである必要があります。

これを回避できた唯一の方法は、アセンブリ内のアンマネージ コードからメソッド呼び出しを実行し、呼び出し後に ESP レジスタのポップ (4 を追加) をスキップすることです (呼び出しの引数には 1 つのパラメーターがあるため、'4 ')。これにより、__clrcall を効果的に実行できます。そのオプションは非常に悪臭を放ちます。

この問題を回避する方法について誰かアイデアがありますか? きっとできるはずです。単純だが重要な情報が欠けています。

これが私のデリゲート定義です (これらはすべて単一の参照クラス ManagedSensor に属します)。

        delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);

これが呼び出したいインスタンスメソッドです

        void LocalOxpMeasurementCallback(std::vector<OBX> *obxes);

次に、ref クラス コンストラクターで行われる ref クラス関数のアンマネージ関数へのマーシャリングを示します。

    // Now to make the 'delegate' unmanaged function pointer usable for unmanged code
    // The argument is the unmanaged callback.
    OxpOnReceivedMeasurement ^oxpMeasurementCallbackFP = gcnew OxpOnReceivedMeasurement(this, &ManagedSensor::LocalOxpMeasurementCallback);
    // Lock it so the garbage collector doesnt get rid of it or move it
    gch = GCHandle::Alloc(oxpMeasurementCallbackFP);
    // Pass the marshaled function pointer to the unmanaged code
    IntPtr ip = Marshal::GetFunctionPointerForDelegate(oxpMeasurementCallbackFP);
    // fnOnReceiveMeasurement is defined in OxpLibTransports.h which matches the delegate
    // this passes the function pointer to the unmanaged Sensor class to be used when a 
    // measurement is received
    _sensor->RegisterForMeasurementCallback((fnOnReceiveMeasurement)(ip.ToPointer()));

誰かがこの問題に対する良い答えを持っていることを願っています。私はおそらく愚かな何かを見逃しています。

4

1 に答える 1

7

それはサポートされています。属性を使用して、デリゲート用に作成するサンクが __cdecl 呼び出し規約を使用する必要があることを CLR に伝えることができます。次のようにします。

using namespace System::Runtime::InteropServices;

[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
delegate void OxpOnReceivedMeasurement(std::vector<OBX> *obxes);
于 2013-04-28T17:35:50.707 に答える