1

私は.hファイルとそれらに付随する.libファイルのサードパーティコレクションを持っています。これらのネイティブ C++ ファイルを C++/CLI ラッパーでラップし、C# から最終的な呼び出しを行っています。明示的に変更しない限り、ラッパーで値が変更されない参照が渡されることを期待するメソッドを呼び出すと、問題が発生します。

現在、私の C++/CLI ラッパー コードは次のようになっています。

bool get_testInt16(int16% testInt16)
{
   int16* t = static_cast<int16*>(GCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer());
   bool b = m_NativeCMTY_TestData->get_testInt16(*t);
   testInt16 = *t;
   return b;
};

対応するネイティブ C++ コードは次のようになります。

bool get_testInt16(int16 &testInt16);

もっと良い方法があるはずだと思いますが、そうではないでしょうか?もっと良い方法があることを望んでいるとだけ言っておきましょう!

4

2 に答える 2

4

オプションは次のとおりです。

bool get_testInt16(int16% testInt16)
{
   int16 t = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(t);
   testInt16 = t;
   return b;
};

したがって、単純にローカル ネイティブ変数を作成し、巨大なキャストや .NET ポインターを回避します。

于 2009-08-03T16:36:49.543 に答える
0

の代わりにピン留めポインターを使用していない理由はGCHandle::ToIntPtr(GCHandle::Alloc(testInt16)).ToPointer()何ですか?

また、このように参照値を固定するのは遅すぎます。

参照がスタック値への参照である場合は不要です。インスタンス フィールドへの参照である場合、呼び出し元のコードは実際にオブジェクトを固定する必要があります (ただし、これはアンマネージド セムティクスのマネージド コードへの厄介なリークですが、少なくとも次の動作になります)。メソッドをクリアします。

ref パラメーターは非常に小さいため、すべてのピニングを完全に回避し、スタック上に一時的なピニングを作成し、それをアンマネージ関数に渡し、それを元の関数に書き戻すことは理にかなっています。

bool get_testInt16(int16% testInt16)
{
   int16 temp = testInt16;
   bool b = m_NativeCMTY_TestData->get_testInt16(temp);
   testInt16 = temp;
   return b;
};
于 2009-08-03T16:40:20.147 に答える