2015-06-13 3 views
5

У меня есть следующий класс:Получить без явного поля смещения

[StructLayout(LayoutKind.Sequential)] 
class Class 
{ 
    public int Field1; 
    public byte Field2; 
    public short? Field3; 
    public bool Field4; 
} 

Как я могу получить байт смещения Field4, начиная с начала (или заголовка объекта) данных класса?
Для иллюстрации:

Class cls = new Class(); 
fixed(int* ptr1 = &cls.Field1) //first field 
fixed(bool* ptr2 = &cls.Field4) //requested field 
{ 
    Console.WriteLine((byte*)ptr2-(byte*)ptr1); 
} 

Полученное смещение, в данном случае, 5, потому что на самом деле во время выполнения перемещает Field3 до конца типа (и его колодки), вероятно, потому что его тип является общим. Я знаю, что есть Marshal.OffsetOf, но он возвращает неуправляемое смещение, а не управление.

Как получить это смещение от экземпляра FieldInfo? Есть ли какой-либо метод .NET, который используется для этого, или я должен написать свой собственный, принимая во внимание все исключения (размер шрифта, заполнение, явные смещения и т. Д.)?

+0

@usr Meant 'Field3'. На самом деле, это изменено, к моему удивлению. Он переместил это поле в конец класса, заполнив его (отладка и выпуск, 32-разрядная версия). Это может иметь какое-то отношение к невозможности получения указателей общих типов. – IllidanS4

+1

Вы не можете узнать, макет управляемых объектов - это деталь реализации. Кроме того, через бэкдор вы уже обнаружили. CLR использует это для оптимизации макета, делая объект как можно меньшим, сохраняя при этом гарантии выравнивания. [StructLayout] соблюдается только в маршалированных структурах. В этом случае Marshal.SizeOf() дает вам смещение. –

+1

@Hans But Marshal.SizeOf возвращает неуправляемый размер шрифта, а не управляемый. Я думал, что LayoutKind.Explicit почитается в структурах, перекрывая поля, являющиеся доказательством этого, без сортировки. – IllidanS4

ответ

2

С некоторыми трюками около TypedReference.MakeTypedReference, можно получить ссылку на это поле и на начало данных объекта, а затем просто вычесть. Метод можно найти в SharpUtils.

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