C# 字节数组转换成固定的整数指针

7

有没有可能以某种方式转换由fixed()语句创建的指针的类型?

这是情况:

我有一个字节数组,我想遍历它,但我想将值视为int,因此有int *而不是byte *。

下面是一些示例代码:

byte[] rawdata = new byte[1024];

fixed(int* ptr = rawdata) //this fails with an implicit cast error
{
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}

不进行迭代过程中的强制类型转换,是否也能实现这一操作?


2
为什么要在C#中使用指针?要迭代它,您可以简单地使用“for”循环。 - Amar Palsapure
同意。虽然从一开始就表达你的意图有助于提供答案并避免问题 :) - Timo
3个回答

8
byte[] rawdata = new byte[1024];

fixed(byte* bptr = rawdata)
{
    int* ptr=(int*)bptr;
    for(int i = idx; i < rawdata.Length; i++)
    {
        //do some work here
    }
}

你实际上没有移动指针,向用户展示这一点可能是一个好主意。你还应该提到字节大小的差异。 - Guvante

8

我相信您需要通过一个 byte* 来实现。例如:

using System;

class Test
{
    unsafe static void Main()
    {
        byte[] rawData = new byte[1024];
        rawData[0] = 1;
        rawData[1] = 2;

        fixed (byte* bytePtr = rawData)
        {
            int* intPtr = (int*) bytePtr;
            Console.WriteLine(intPtr[0]); // Prints 513 on my box
        }
    }
}

请注意,在迭代时,如果您将字节数组视为32位值序列,则应使用rawData.Length / 4而不是rawData.Length


什么是处理任何剩余字节的最佳方法,这些剩余字节通过指针算术无法平均分成 sizeof(int)?(例如,如果字节数组长度为1023个字节。) - Quick Joe Smith
@QuickJoeSmith:我可能不会使用指针算术来处理它们。 - Jon Skeet

2

我发现了一种看起来更优雅,而且出于某种原因也更快的方法:

        byte[] rawData = new byte[1024];
        GCHandle rawDataHandle = GCHandle.Alloc(rawData, GCHandleType.Pinned);
        int* iPtr = (int*)rawDataHandle.AddrOfPinnedObject().ToPointer();
        int length = rawData.Length / sizeof (int);

        for (int idx = 0; idx < length; idx++, iPtr++)
        {
            (*iPtr) = idx;
            Console.WriteLine("Value of integer at pointer position: {0}", (*iPtr));
        }
        rawDataHandle.Free();

这样,除了设置正确的迭代长度之外,我需要做的唯一一件事情就是增加指针。我将代码与使用fixed语句的代码进行比较,发现这个代码略微更快。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接