Что такое фиксированный буфер?
Из MSDN:
В C # вы можете использовать оператор fixed для создания буфера с массивом фиксированного размера в структуре данных. Это полезно, когда вы работаете с существующим кодом, например кодом, написанным на других языках, уже существующими библиотеками DLL или COM-проектами. Фиксированный массив может принимать любые атрибуты или модификаторы, разрешенные для обычных членов структуры. Единственное ограничение - тип массива должен быть bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float или double.
Я просто процитирую г-на Ханса Пассана относительно того, почему фиксированный буфер ДОЛЖЕН быть unsafe
. Вы можете увидеть Почему буферы фиксированного размера (массивы) должно быть небезопасно? для получения дополнительной информации.
Потому что «фиксированный буфер» - это не настоящий массив. Это настраиваемый тип значения, единственный известный мне способ его создания на языке C #. Среда CLR не может проверить безопасное выполнение индексации массива. Код также не поддается проверке. Наиболее наглядная демонстрация этого:
using System;
class Program {
static unsafe void Main(string[] args) {
var buf = new Buffer72();
Console.WriteLine(buf.bs[8]);
Console.ReadLine();
}
}
public struct Buffer72 {
public unsafe fixed byte bs[7];
}
В этом примере вы можете произвольно обращаться к кадру стека. Стандартный метод внедрения переполнения буфера будет доступен для вредоносного кода, чтобы исправить адрес возврата функции и заставить ваш код перейти в произвольное место.
Да, это небезопасно.
Почему фиксированный буфер не может содержать непримитивные типы данных?
Саймон Уайт поднял обоснованный вопрос:
Я собираюсь добавить «дополнительные сложности к компилятору». Компилятору необходимо будет проверить, не применялись ли какие-либо специфические функции .NET к структуре, применяемой к перечисляемым элементам. Например, универсальные шаблоны, реализация интерфейса, даже более глубокие свойства непримитивных массивов и т. Д. Несомненно, среда выполнения также будет иметь некоторые проблемы взаимодействия с подобными вещами.
И Ибаса:
«Но это уже сделано компилятором». Только частично. Компилятор может выполнять проверки, чтобы увидеть, управляется ли тип, но при этом не заботится о генерации кода для чтения / записи структур в фиксированные буферы. Это можно сделать (на уровне CIL ничто не мешает), это просто не реализовано в C #.
Наконец, Мехрдад:
Я думаю, это буквально потому, что они не хотят, чтобы вы использовали буферы фиксированного размера (потому что они хотят, чтобы вы использовали управляемый код). Слишком легкое взаимодействие с машинным кодом снижает вероятность использования .NET для всего, и они хотят максимально продвигать управляемый код.
Ответ звучит однозначно: «это просто не реализовано».
Почему не реализовано?
Мое предположение состоит в том, что затраты и время на внедрение для них просто не стоят того. Разработчики предпочли бы управляемый код неуправляемому. Возможно, это будет сделано в будущей версии C #, но текущая среда CLR лишена необходимой сложности.
Альтернативой может быть проблема безопасности. Поскольку фиксированные буферы чрезвычайно уязвимы для всевозможных проблем и угроз безопасности, если они будут плохо реализованы в вашем коде, я могу понять, почему их использование не рекомендуется по сравнению с управляемым кодом на C #. Зачем тратить много сил на то, от чего вы не хотите отказываться?
person
DanteTheEgregore
schedule
30.09.2013