固定大小的缓冲区(C# 编程指南)Fixed Size Buffers (C# Programming Guide)

在 C# 中,可以使用 fixed 语句来创建在数据结构中具有固定大小的数组的缓冲区。In C#, you can use the fixed statement to create a buffer with a fixed size array in a data structure. 当编写与其他语言或平台的数据源进行互操作的方法时,固定大小的缓冲区很有用。Fixed size buffers are useful when you write methods that interop with data sources from other languages or platforms. 固定的数组可以采用允许用于常规结构成员的任何属性或修饰符。The fixed array can take any attributes or modifiers that are allowed for regular struct members. 唯一的限制是数组类型必须为 boolbytecharshortint, longsbyteushortuintulongfloatdoubleThe only restriction is that the array type must be bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double.

private fixed char name[30];

备注Remarks

在安全代码中,包含数组的 C# 结构不包含该数组元素。In safe code, a C# struct that contains an array does not contain the array elements. 而该结构包含对元素的引用。Instead, the struct contains a reference to the elements. 当在不安全的代码块中使用数组时,可以在结构中嵌入该固定大小的数组。You can embed an array of fixed size in a struct when it is used in an unsafe code block.

以下 struct 的大小为 8 字节。The following struct is 8 bytes in size. pathName 数组是引用:The pathName array is a reference:

public struct PathArray
{
    public char[] pathName;
    private int reserved;
}

struct 可以在不安全代码中包含嵌入的数组。A struct can contain an embedded array in unsafe code. 在下面的示例中,fixedBuffer 数组具有固定的大小。In the following example, the fixedBuffer array has a fixed size. 使用 fixed 语句建立指向第一个元素的指针。You use a fixed statement to establish a pointer to the first element. 通过此指针访问数组的元素。You access the elements of the array through this pointer. fixed 语句将 fixedBuffer 实例字段固定到内存中的特定位置。The fixed statement pins the fixedBuffer instance field to a specific location in memory.

internal unsafe struct MyBuffer
{
    public fixed char fixedBuffer[128];
}

internal unsafe class MyClass
{
    public MyBuffer myBuffer = default;
}

private static void AccessEmbeddedArray()
{
    MyClass myC = new MyClass();

    unsafe
    {
        // Pin the buffer to a fixed location in memory.
        fixed (char* charPtr = myC.myBuffer.fixedBuffer)
        {
            *charPtr = 'A';
        }
        // Access safely through the index:
        char c = myC.myBuffer.fixedBuffer[0];
        Console.WriteLine(c);
        // modify through the index:
        myC.myBuffer.fixedBuffer[0] = 'B';
        Console.WriteLine(myC.myBuffer.fixedBuffer[0]);
    }

}

包含 128 个元素的 char 数组的大小为 256 个字节。The size of the 128 element char array is 256 bytes. 固定大小的 char 缓冲区每个字符始终占用两个字节,而不考虑编码。Fixed size char buffers always take two bytes per character, regardless of the encoding. 甚至在将 char 缓冲区封送到 API 方法或具有 CharSet = CharSet.AutoCharSet = CharSet.Ansi 的结构时,这也为 true。This is true even when char buffers are marshaled to API methods or structs with CharSet = CharSet.Auto or CharSet = CharSet.Ansi. 有关更多信息,请参见CharSetFor more information, see CharSet.

前面的示例演示访问未固定的 fixed 字段,此功能从 C# 7.3 开始提供。The preceding example demonstrates accessing fixed fields without pinning, which is available starting with C# 7.3.

另一常见的固定大小的数组是 bool 数组。Another common fixed-size array is the bool array. bool 数组中的元素大小始终为一个字节。The elements in a bool array are always one byte in size. bool 数组不适用于创建位数组或缓冲区。bool arrays are not appropriate for creating bit arrays or buffers.

备注

除了通过使用 stackalloc 创建的内存外,C# 编译器和公共语言运行时 (CLR) 不执行任何安全缓冲区溢出检查。Except for memory created by using stackalloc, the C# compiler and the common language runtime (CLR) do not perform any security buffer overrun checks. 与所有不安全代码一样,请谨慎使用。As with all unsafe code, use caution.

不安全的缓冲区与常规数组的区别体现在以下方面:Unsafe buffers differ from regular arrays in the following ways:

  • 只能在不安全的上下文中使用不安全的缓冲区。You can only use unsafe buffers in an unsafe context.
  • 不安全的缓冲区始终是矢量或一维数组。Unsafe buffers are always vectors, or one-dimensional arrays.
  • 数组的声明应包括计数,如 char id[8]The declaration of the array should include a count, such as char id[8]. 不能使用 char id[]You cannot use char id[].
  • 在不安全的上下文中,不安全的缓冲区只能是结构的实例字段。Unsafe buffers can only be instance fields of structs in an unsafe context.

请参阅See also