はになる可能性がありますが、ポインタをループするコードを書く必要があり、ネイティブメモリからデータを読み込み、管理対象にコピーする必要がありますメモリ空間。代わりにシンプルな構造体の配列をお勧めします。
あなたは...(32ビットint型を仮定して)次...
struct Point
{
int x;
int y;
int z;
}
のようなCの構造体を持っているなら、あなたは、C#でほとんど同じ方法でそれを表現したい:
[StructLayout(LayoutKind.Sequential]
struct Point
{
public int x;
public int y;
public int z;
}
今度は配列を返すようにすると、ネイティブコードで配列を割り当ててポインタとして戻し、要素のサイズを指定する別のポインタを渡すのが最も簡単です。
あなたのCのプロトタイプは次のようになります。
// Return value would represent an error code
// (in case something goes wrong or the caller
// passes some invalid pointer, e.g. a NULL).
// Caller must pass in a valid pointer-to-pointer to
// capture the array and a pointer to capture the size
// in elements.
int GetPoints(Point ** array, int * arraySizeInElements);
P /呼び出しの宣言は、このようになります:
[DllImport("YourLib.dll")]
static extern int GetPoints(
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] out Point[] array,
out int arraySizeInElements);
MarshalAs
属性は、配列が指定したサイズを使用してマーシャリングすることを指定します2番目のパラメータ(詳細はMSDN "Default Marshaling for Arrays")を参照してください。
CoTaskMemAlloc
を使用してネイティブバッファを割り当てる必要があることに注意してください。これは、.NETマーシャラが期待するとおりです。そうしないと、アプリケーションでメモリリークやその他のエラーが発生します。ここで
は私の答えを確認しながら、私はコンパイルされ、簡単な例から抜粋です:
struct Point
{
int x;
int y;
int z;
};
extern "C"
int GetPoints(Point ** array, int * arraySizeInElements)
{
// Always return 3 items for this simple example.
*arraySizeInElements = 3;
// MUST use CoTaskMemAlloc to allocate (from ole32.dll)
int bytesToAlloc = sizeof(Point) * (*arraySizeInElements);
Point * a = static_cast<Point *>(CoTaskMemAlloc(bytesToAlloc));
*array = a;
Point p1 = { 1, 2, 3 };
a[0] = p1;
Point p2 = { 4, 5, 6 };
a[1] = p2;
Point p3 = { 7, 8, 9 };
a[2] = p3;
return 0;
}
管理、発信者は、その後、(この例では、私は内部のすべての相互運用のコードを入れて非常に簡単にデータを扱うことができますNativeMethods
と呼ばれる静的クラス):
NativeMethods.Point[] points;
int size;
int result = NativeMethods.GetPoints(out points, out size);
if (result == 0)
{
Console.WriteLine("{0} points returned.", size);
foreach (NativeMethods.Point point in points)
{
Console.WriteLine("({0}, {1}, {2})", point.x, point.y, point.z);
}
}
これは優れているようです。 CoTAskMemAllocについて知りませんでした。ありがとうございました – user978281