Буферы фиксированного размера (Руководство по программированию на C#)
В языке C# для создания буфера с массивом фиксированного размера в структуре данных можно использовать оператор fixed. Это полезно при работе с существующим кодом, например с кодом, написанным на других языках, ранее созданными библиотеками DLL или проектами COM. Фиксированный массив может принимать любые атрибуты или модификаторы, допустимые для обычных членов структуры. Единственным ограничением является то, что массив должен иметь тип bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float или double.
private fixed char name[30];
Заметки
В предыдущих версиях языка C# объявление структуры фиксированного размера в стиле C++ было затруднительным, так как структура C# с массивом не содержит элементы массива. Вместо этого структура содержит ссылку на элементы.
В языке C# версии 2.0 появилась возможность встраивания массива фиксированного размера в структуру, если он используется в блоке небезопасного кода.
Например, до C# 2.0 следующая struct имела бы размер 8 байт. Массив pathName является ссылкой на выделенный в куче массив:
public struct MyArray
{
public char[] pathName;
private int reserved;
}
Начиная с версии 2.0 языка C# struct может содержать встроенный массив. В следующем примере массив fixedBuffer имеет фиксированный размер. Для доступа к элементам такого массива используется оператор fixed, устанавливающий указатель на первый элемент. Оператор fixed закрепляет экземпляр fixedBuffer в определенном месте в памяти.
namespace FixedSizeBuffers
{
internal unsafe struct MyBuffer
{
public fixed char fixedBuffer[128];
}
internal unsafe class MyClass
{
public MyBuffer myBuffer = default(MyBuffer);
}
internal class Program
{
static void Main()
{
MyClass myC = new MyClass();
unsafe
{
// Pin the buffer to a fixed location in memory.
fixed (char* charPtr = myC.myBuffer.fixedBuffer)
{
*charPtr = 'A';
}
}
}
}
}
Размер массива из 128 элементов char составляет 256 байт. В буферах фиксированного размера char на один символ всегда приходится два байта, независимо от кодировки. Это справедливо даже в том случае, когда буферы char маршалируются в методы API или структуры с CharSet = CharSet.Auto или CharSet = CharSet.Ansi. Дополнительные сведения см. в разделе CharSet.
Еще одним распространенным массивом фиксированного размера является массив bool. Элементы в массиве bool всегда имеют размер в один байт. Массивы bool не подходят для создания битовых массивов или буферов.
Примечание
За исключением памяти, созданной при помощи stackalloc, компилятор C# и среда CLR не выполняют проверку переполнения буфера безопасности.Как и при работе с любым небезопасным кодом следует проявлять осторожность.
Небезопасные буферы отличаются от обычных массивов следующим:
Небезопасные буферы можно использовать в небезопасном контексте.
Небезопасные буферы это всегда векторы или одномерные массивы.
В объявлении массива всегда должен присутствовать счетчик, такой как char id[8]. При этом char id[] нельзя использоваться.
Небезопасные буферы могут быть только полями экземпляра структур в небезопасном контексте.
См. также
Ссылки
Небезопасный код и указатели (Руководство по программированию в C#)
Оператор fixed (Справочник по C#)
Взаимодействие (Руководство по программированию в C#)