2011-02-01 3 views
3

Мне было интересно узнать о некоторых материалах сериализации, поэтому я пошёл вокруг FormatterServices и нашел метод под названием nativeGetUninitializedObject, который фактически обрабатывает инициализацию (без вызова кустартера) заданного типа. Этот метод украшен ключевым словом extern и имеет следующий атрибут: [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]Где на самом деле существует nativeGetUninitializedObject?

Мне осталось интересно: где этот метод фактически существует? Какой код вызывает CLR для получения инициализированного данного типа (без вызова конструктора)?

ответ

4

Этот метод фактически существует в нативной части CLR. MethodImplOptions.InternalCall обозначает вызов, который перенаправляется на собственный код CLR и реализуется там.

От MSDN:

Определяет внутренний вызов. Внутренний вызов - это вызов метода, который реализован в самой общей среде выполнения языка.

6

Метод существует в CLR. Компилятор JIT имеет доступ к таблице внутри CLR, содержащей адреса всех функций MethodImplOptions.InternalCall. В разделе таблицы, это отношение к вашему вопросу выглядит в исходном коде SSCLI20 (CLR/SRC/VM/ecall.cpp):

FCFuncStart(gSerializationFuncs) 
    FCFuncElement("nativeGetSafeUninitializedObject", ReflectionSerialization::GetSafeUninitializedObject) 
    FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject) 
FCFuncEnd() 

Для JIT вызова метода, он просто ищет имя функции в этой таблице и генерирует прямую инструкцию CALL для адреса функции, как указано в таблице. Очень быстрый, прямой переход от управляемого кода к коду, написанному на C++ внутри CLR.

Метод ReflectionSerialization :: GetUninitializedObject() живет внутри clr/src/vm/reflectioninvocation.cpp, он слишком велик, чтобы публиковать здесь. Вы можете посмотреть исходный код загружаемого SSCLI20. Там есть куча проверки ошибок, а затем вызов необработанного метода Allocate() для выделения памяти для объекта. Нет вызова конструктора.

Смежные вопросы