C#からC ++への参照渡しのより良い方法は?
-
11-07-2019 - |
質問
サードパーティの.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);
もっと良い方法があるはずだと思うが、そうでないかもしれない?もっといい方法があると言ってみましょう!
解決
オプションは次のとおりです。
bool get_testInt16(int16% testInt16)
{
int16 t = testInt16;
bool b = m_NativeCMTY_TestData->get_testInt16(t);
testInt16 = t;
return b;
};
したがって、ローカルネイティブ変数を作成するだけで、巨大なキャストや.NETポインターを回避できます。
他のヒント
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;
};
所属していません StackOverflow