短い答えは、これは直接行うことはできません。その理由は、変換機能を渡すと、従来のインデックス対応コンテナ(System.Array
、Collections.IList
、ArrayList
など)は、インデックス操作を実行すると結果がSystem.Object
にキャストされます。 C#のポインタはObject
から派生しないので、SystemNotSupported
または同様の例外が発生します。
2つの合理的な回避策があります。
- は メソッドを呼び出す前にポインタ配列をvoidへのポインタ配列に変換します。
- メソッドを呼び出す前に、ポインタ配列をvoidポインタポインタに変換します。
最初のものは、配列の内容全体をforループで複製する必要があるため、やや面倒です。 2番目のオプションは、管理されたSystem.Array
オブジェクトでラップされていないため、配列の長さを渡す必要があります。
サンプルコード
方法:
unsafe Array ToIntPtrArray(void** a, int count)
{
IntPtr[] intPtrArray = new IntPtr[count];
for (int n = 0; n < count; n++)
intPtrArray[n] = new IntPtr(a[n]);
return intPtrArray;
}
使用例(整数ポインタ配列):
int*[] intPtrArray;
// Code that initializes the values of intPtrArray
fixed(int** ptr = &intPtrArray[0])
{
Array result = ToIntPtrArray((void**)ptr, intPtrArray.Length);
}
使用例(ボイドポインタポインタ配列):
void**[] voidPtrPtrArray;
// Code that initializes the values of voidPtrPtrArray
fixed(void*** ptr = &voidPtrPtrArray[0])
{
Array result = ToIntPtrArray((void**)ptr, voidPtrPtrArray.Length);
}
使用例(多次元INTポインタ配列):
int*[,] int2dArray;
// Code that initializes the values of int2dArray
fixed(int** ptr = &int2dArray[0,0])
{
Array result = ToIntPtrArray((void**)ptr, TotalSize(int2dArray));
Array reshaped = ReshapeArray(result,int2dArray);
}
TotalSize
とReshapeArray
は、多次元配列に対処するために書かれているヘルパー関数です。これを達成するためのヒントについては、Programatically Declare Array of Arbitrary Rankを参照してください。
'void *'の数値は? –
明示的な型変換を試してください。私はあなたの関数には未定義の動作がたくさんあると確信しています。 –
@CédricBignon私はあなたの質問をよく理解していません。 'void *'型の変数は、プラットフォームに依存するアドレス範囲内に任意の数値を持つことができ、いずれの場合でもそのプラットフォーム上の 'IntPtr'に収まるでしょう。この場合、どのように動作するかを示す例を追加しました。 –