c# - 将指针数组转换为 IntPtr 数组

标签 c# .net arrays pointers intptr

我被困在一个看似微不足道的任务上,需要你的帮助。

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

System.Array ToIntPtrArray(System.Array a)

其中实际参数可以是任何 pointer type 的数组(例如 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;
}

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

最佳答案

简短的回答是,这不能直接完成。原因是,如果您传递任何传统的支持索引的容器(System.ArrayCollections.IListArrayList、等)执行索引操作将尝试将结果转换为 System.Object。 C# 中的指针不是从 Object 派生的,因此这将导致 SystemNotSupported 或类似的异常。

有两种合理的解决方法:

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

第一个比较麻烦,因为它需要用 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;
    }

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

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);
}

其中 TotalSizeReshapeArray 是为处理多维数组而编写的辅助函数。有关如何完成此操作的提示,请参阅:Programatically Declare Array of Arbitrary Rank .

关于c# - 将指针数组转换为 IntPtr 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17816846/

相关文章:

c# - Entity Framework 继承 - 仅检索父类型

python - 在另一个数组中查找一个数组的匹配索引

c# - 带有列表或参数的测试用例

c# - 使用 Swagger 的特定状态代码的响应模型

c# - "代替引号 (")

.net - WPF/Silverlight - Prism - 初学者资源

c# - 是否可以在 WPF DataGrid 中获取嵌套列?

windows - delphi中的动态数组和wininet?

Java:在对象类内部创建数组?

c# - datagridview 不允许用户删除行