ОБНОВЛЕНИЕ: теперь есть принятый ответ, который "работает". Вы никогда не должны когда-либо использовать его. Когда-либо.
Сначала позвольте мне предисловие к моему вопросу, заявив, что я разработчик игр. Там есть законная, если очень необычная причина, связанная с производительностью, желающая сделать это.
Скажем, у меня есть класс С# следующим образом:
class Foo
{
public int a, b, c;
public void MyMethod(int d) { a = d; b = d; c = a + b; }
}
Ничего необычного. Обратите внимание, что это ссылочный тип, содержащий только типы значений.
В управляемом коде я хотел бы иметь что-то вроде этого:
Foo foo;
foo = Voodoo.NewInUnmanagedMemory<Foo>(); // <- ???
foo.MyMethod(1);
Как бы выглядела функция NewInUnmanagedMemory
? Если это невозможно сделать в С#, можно ли это сделать в IL? (Или, может быть, С++/CLI?)
В принципе: есть ли способ - как бы хаки - не превратить какой-то полностью произвольный указатель в ссылку на объект. И - не допустить, чтобы CLR взорвался - прокляните последствия.
(Еще один способ поставить вопрос: "Я хочу реализовать пользовательский распределитель для С#" )
Это приводит к следующему вопросу: что делает сборщик мусора (если это необходимо для реализации), когда сталкивается с ссылкой, указывающей вне управляемой памяти?
И, связанный с этим, что произойдет, если Foo
имеет ссылку как поле участника? Что, если он указал на управляемую память? Что делать, если он только указывал на другие объекты, выделенные в неуправляемой памяти?
Наконец, если это невозможно: почему?
Обновление: Ниже приведены "недостающие части":
# 1: Как преобразовать IntPtr
в ссылку на объект? Возможно, это будет возможно хотя и непроверяемый IL (см. Комментарии). До сих пор мне не повезло. Структура, по-видимому, чрезвычайно тщательна, чтобы это не происходило.
(Также было бы неплохо иметь возможность получать информацию о размере и макете для не-blittable управляемых типов во время выполнения. Опять же, структура пытается сделать это невозможным.)
# 2: Предполагая, что проблема может быть решена - что делает GC, когда она встречает ссылку на объект, которая указывает вне кучи GC? Это крушение? Антон Тихий, в своем ответе, догадывается, что так оно и будет. Учитывая, насколько осторожна структура, чтобы предотвратить # 1, это кажется вероятным. Что-то, что подтверждает это, было бы неплохо.
(Альтернативно ссылка на объект может указывать на закрепленную память внутри кучи GC. Разве это имеет значение?)
Исходя из этого, я склонен думать, что эта идея для взлома невозможна или, по крайней мере, не стоит усилий. Но мне было бы интересно получить ответ, который входит в технические детали №1 или №2 или обоих.