C#缓冲区解释

3
这可能是一个初学者的问题,但我一直在阅读相关内容,发现很难理解。
这是msdn页面关于该主题的示例(仅略小)。
using System;

class SetByteDemo
{
    // Display the array contents in hexadecimal.
    public static void DisplayArray(Array arr, string name)
    {
        // Get the array element width; format the formatting string.
        int elemWidth = Buffer.ByteLength(arr) / arr.Length;
        string format = String.Format(" {{0:X{0}}}", 2 * elemWidth);

        // Display the array elements from right to left.
        Console.Write("{0,7}:", name);
        for (int loopX = arr.Length - 1; loopX >= 0; loopX--)
            Console.Write(format, arr.GetValue(loopX));
        Console.WriteLine();
    }

    public static void Main()
    {
        // These are the arrays to be modified with SetByte.
        short[] shorts = new short[2];

        Console.WriteLine("Initial values of arrays:\n");

        // Display the initial values of the arrays.
        DisplayArray(shorts, "shorts");

        // Copy two regions of source array to destination array,
        // and two overlapped copies from source to source.
        Console.WriteLine("\n" +
            "  Array values after setting byte 1 = 1 and byte 3 = 200\n");
        Buffer.SetByte(shorts, 1, 1);
        Buffer.SetByte(shorts, 3, 10);

        // Display the arrays again.
        DisplayArray(shorts, "shorts");
        Console.ReadKey();
    }
}

SetByte 应该很容易理解,但是如果在进行 SetByte 操作之前打印 shorts 数组,则该数组看起来像这样

{short[2]}
    [0]: 0
    [1]: 0

在执行第一个Buffer.SetByte(shorts, 1, 1);之后,数组变为

{short[2]}
    [0]: 256
    [1]: 0

在设置Buffer.SetByte(shorts, 3, 10);之后,数组变为

{short[2]}
    [0]: 256
    [1]: 2560

在最后,示例中他们从右到左打印数组:
0A00 0100

我不明白这是如何工作的,能否有人给我一些相关信息?
3个回答

3
Buffer类允许您像在c中使用void指针一样操纵内存,它是在.net上以快速的方式操作内存的memcpy、memset等的总和。
当您传递“shorts”数组时,Buffer类将其视为指向四个连续字节(两个short,每个short为两个字节)的指针。
  |[0][1]|[2][3]|
   short  short

所以未初始化的数组看起来像这样:
 |[0][0]|[0][0]|
  short  short

当你执行 Buffer.SetByte(shorts, 1, 1); 操作时,你就告诉了 Buffer 类去改变字节数组的第二个字节,因此它会变成:

|[0][1]|[0][0]|
 short  short

如果你将两个字节(0x00, 0x01)转换为short类型,结果为0x0100(注意这两个字节一个接一个,但是顺序是反过来的,这是因为C#编译器使用小端序),即256。

第二行基本上做了相同的事情:Buffer.SetByte(shorts, 3, 10);将第三个字节改为10:

|[0][1]|[0][10]|
 short  short

然后将0x00、0x0A转换为短整型,得到的结果是0x0A00或者2560。


2
.NET 类型使用小端字节序。这意味着 shortint 等的第一个字节(实际上是第零个字节)包含最低有效位。
设置数组后,它看起来像这样:byte[]
0, 1, 0, 10

作为short[],它的解释如下:
0 + 1*256 = 256, 0 + 10*256 = 2560

0
我认为人们可能会遇到困难的部分是Buffer.SetByte()方法基本上是以不同于使用数组索引器[]进行常规赋值的方式迭代数组,后者将根据包含类型(shorts/doubles/etc.)的宽度而不是字节来分离数组...以您的示例为例: 短数组通常被视为 arr = [xxxx, yyyy](在16进制中) 但SetByte方法“看到”的是: arr = [xx, yy, zz, ww] 因此,像Buffer.SetByte(arr, 1, 5)这样的调用将寻址数组中的第二个字节,该字节仍然位于第一个short内。设置该值即可。结果应如下所示:
[05 00, 00 00] 十六进制或 [1280,0]。

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