2

C++/CLI メソッド がManagedMethodあり、ネイティブ メソッドによって変更される出力引数が 1 つあります。

// file: test.cpp

#pragma unmanaged
void NativeMethod(int& n)
{
   n = 123;
}
#pragma managed

void ManagedMethod([System::Runtime::InteropServices::Out] int% n)
{
   pin_ptr<int> pinned = &n;
   NativeMethod(*pinned);
}

void main()
{
   int n = 0;
   ManagedMethod(n);
   // n is now modified
}

ManagedMethod戻ると、期待どおりに の値がn変更されています。これまでのところ、これをコンパイルすることができた唯一の方法はpin_ptrinsideを使用するManagedMethodことなので、実際に固定することはこれを行うための正しい/唯一の方法ですか? または、に渡すよりエレガントな方法はありnますNativeMethodか?

4

1 に答える 1

2

はい、これが正しい方法です。CLR 内で非常に高度に最適化されているため、変数は [pinned] 属性を取得するため、CLR は、移動してはならないオブジェクトへの内部ポインターを格納していることを認識します。GCHandle::Alloc() とは異なり、pin_ptr<> は別のハンドルを作成せずに実行できます。メソッドをコンパイルするときにジッターが生成されることがテーブルに報告されています。GC はそのテーブルを使用して、オブジェクトのルートを探す場所を認識します。

これは、NativeMethod() が実行されているのとまったく同時にガベージ コレクションが発生した場合にのみ問題になります。実際にはあまり頻繁には発生しません。プログラムでスレッドを使用する必要があります。YMMV。

それを行う別の方法があります。ピン留めは必要ありませんが、もう少しマシンコードが必要です。

void ManagedMethod(int% n)
{
    int copy = n;
    NativeMethod(copy);
    n = copy;
}

ローカル変数にはスタックストレージがあり、ガベージコレクターによって移動されないため、これは機能します。スタイルのエレガンスポイントを獲得することはできませんが、私が通常自分で使用しているものは、ピン留めの副作用を見積もることはそれほど簡単ではありません. しかし、実際には、pin_ptr<> を恐れる必要はありません。

于 2016-03-04T21:25:25.170 に答える