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

前端之家收集整理的这篇文章主要介绍了c# – 将指针数组转换为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.Array,Collections.IList,ArrayList等)都将尝试将结果转换为System.Object. C#中的指针不派生自Object,所以这将导致SystemNotSupported或类似异常.

有两个合理的解决方法

>在调用之前将指针数组转换为void指针数组
方法.
>将指针数组转换为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;
    }

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

int*[] intPtrArray;

// Code that initializes the values of intPtrArray

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

示例用法(void pointer pointer array):

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.

猜你在找的C#相关文章