方法: C++ Interop を使用して埋め込みポインターをマーシャリングする
次のコード例では、マネージ、アンマネージ の #pragma ディレクティブを使用してマネージ関数とアンマネージ関数を同じファイル内で実装していますが、これらの関数は、別個のファイルに定義された場合も同じように相互運用できます。 アンマネージ関数のみを含むファイルは、/clr (共通言語ランタイムのコンパイル) でコンパイルする必要はありません。
使用例
次の例は、ポインターを含む構造体を受け取るアンマネージ関数をマネージ関数から呼び出す方法を示します。 マネージ関数は、構造体のインスタンスを作成し、ref new、gcnew (C++ コンポーネント拡張) キーワードの代わりに新しいキーワードを使用して埋め込みポインターを初期化します。 これにより、ネイティブ ヒープ上にメモリが割り当てられるため、ガベージ コレクションを抑制するために配列を固定する必要がなくなります。 ただし、メモリ リークを回避するためにメモリを明示的に削除する必要があります。
// marshal_embedded_pointer.cpp
// compile with: /clr
#include <iostream>
using namespace System;
using namespace System::Runtime::InteropServices;
// unmanaged struct
struct ListStruct {
int count;
double* item;
};
#pragma unmanaged
void UnmanagedTakesListStruct(ListStruct list) {
printf_s("[unmanaged] count = %d\n", list.count);
for (int i=0; i<list.count; i++)
printf_s("array[%d] = %f\n", i, list.item[i]);
}
#pragma managed
int main() {
ListStruct list;
list.count = 10;
list.item = new double[list.count];
Console::WriteLine("[managed] count = {0}", list.count);
Random^ r = gcnew Random(0);
for (int i=0; i<list.count; i++) {
list.item[i] = r->NextDouble() * 100.0;
Console::WriteLine("array[{0}] = {1}", i, list.item[i]);
}
UnmanagedTakesListStruct( list );
delete list.item;
}