Сообщение Re[63]: MS забило на дотнет. Питону - да, сишарпу - нет? от 14.09.2021 8:34
Изменено 14.09.2021 9:20 Serginio1
V>Колега Serginio1 как-то сказал рядом в этом же обсуждении, что ссылка на typeinfo находится по отрицательному смещению VMT (это так в плюсах, и я даже поверил насчёт дотнета, бо давно не всматриваюсь в виртуальные вызовы в дотнете, бо где гоняюсь за эффективностью, там их нет).
Да прошу прощения за недостоверную информацию
https://docs.microsoft.com/en-us/archive/msdn-magazine/2005/may/net-framework-internals-how-the-clr-creates-runtime-objects
Вся правда о TypeHandle в .NET
V>Колега Serginio1 как-то сказал рядом в этом же обсуждении, что ссылка на typeinfo находится по отрицательному смещению VMT (это так в плюсах, и я даже поверил насчёт дотнета, бо давно не всматриваюсь в виртуальные вызовы в дотнете, бо где гоняюсь за эффективностью, там их нет).
Да прошу прощения за недостоверную информацию
https://docs.microsoft.com/en-us/archive/msdn-magazine/2005/may/net-framework-internals-how-the-clr-creates-runtime-objects
Вся правда о TypeHandle в .NET
Ага, значит TypeHandle может быть как указателем на MethodTable, так и указателем на TypeDesc, в зависимости от типа объекта. Для массивов он указывает на TypeDesc. Тип object[][] — это массив, элементами которого являются object[], для которых TypeHandle=TypeDesc. Эта информация объясняет наш пример, но всё ещё остаются некоторые вопросы. Например: а как же отличить, на что именно указывает TypeHandle? Поможет нам в этом дальнейшее изучение исходников CLI:
FORCEINLINE BOOL IsUnsharedMT() const {
LEAF_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
return((m_asTAddr & 2) == 0);
}
FORCEINLINE BOOL IsTypeDesc() const {
WRAPPER_CONTRACT;
return(!IsUnsharedMT());
}Всё зависит от второго бита в адресе: нулевое значение определяет MethodTable, а единичное — TypeDesc. Если мы работаем с шестнадцатеричными адресами, то можно легко определить вид TypeHandle по последней цифре:
MethodTable: 0, 1, 4, 5, 8, 9, C, D
TypeDesc : 2, 3, 6, 7, A, B, E, F
А теперь взглянем ещё раз на дамп памяти нашего примера. Можно видеть, что для System.Object[] в дампе присутствуют указатели как на его TypeDesc, так и на MethodTable. Не смотря на то, что под TypeHandle в данном случае подразумевается TypeDesc, заголовочный указатель для a[0] всё-таки указывает на MethodTable. Поэтому некорректно говорить о том, что в заголовке каждого объекта хранится TypeHandle: там хранится указатель на MethodTable, а это далеко не всегда одно и то же.