将指针数组转换为IntPtr数组

Pet*_*sky 10 .net c# arrays pointers intptr

我陷入了一项看似微不足道的任务,需要你的帮助.

我需要编写一个带有以下签名的方法:

System.Array ToIntPtrArray(System.Array a)
Run Code Online (Sandbox Code Playgroud)

其中一个实际的参数可以是任意的阵列指针类型(例如int*[],long**[],void*[,]),并用类型的元素返回相同形状的阵列System.IntPtr具有相同的数值作为输入数组的元素.问题是如果我事先不知道它们的类型,我不明白如何提取指针的数值.


例如,如果我事先知道我的参数总是类型void*[],我可以编写如下方法:

unsafe IntPtr[] ToIntPtrArray(void*[] a)
{
    var result = new IntPtr[a.Length];
    for (int i = 0; i < a.Length; i++)
        result[i] = (IntPtr) a[i];

    return result;
}
Run Code Online (Sandbox Code Playgroud)

但问题是它可能不是void*[],但是void**[]或其他任何东西,该方法应该能够处理所有情况.

nic*_*las 3

简而言之,这不能直接完成。原因是,如果您传递转换函数,则执行索引操作的任何传统的具有索引功能的容器(System.ArrayCollections.IListArrayList等)都会尝试将结果转换为System.Object。C# 中的指针并非派生自Object,因此这将导致SystemNotSupported类似的异常。

有两种合理的解决方法:

  1. 在调用该方法之前将指针数组转换为 void 指针数组。
  2. 在调用方法之前将指针数组转换为 void 指针。

第一个相当麻烦,因为它需要使用 for 循环复制数组的全部内容。第二个选项需要传入数组的长度,因为它不再用托管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;
    }
Run Code Online (Sandbox Code Playgroud)

用法示例(整数指针数组):

int*[] intPtrArray;

// Code that initializes the values of intPtrArray

fixed(int** ptr = &intPtrArray[0])
{
   Array result = ToIntPtrArray((void**)ptr, intPtrArray.Length);
}
Run Code Online (Sandbox Code Playgroud)

用法示例(空指针指针数组):

void**[] voidPtrPtrArray;

// Code that initializes the values of voidPtrPtrArray

fixed(void*** ptr = &voidPtrPtrArray[0])
{
    Array result = ToIntPtrArray((void**)ptr, voidPtrPtrArray.Length);
}
Run Code Online (Sandbox Code Playgroud)

用法示例(多维 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);
}
Run Code Online (Sandbox Code Playgroud)

其中TotalSizeReshapeArray是为处理多维数组而编写的辅助函数。有关如何实现此目的的提示,请参阅:以编程方式声明任意等级的数组