2015-06-13 9 views
5

Mam następujące klasy:uzyskać bez wyraźnej polu Przesunięcie

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

Jak mogę offset bajtowy Field4 zaczynając od początku danych klasy (lub obiekt nagłówku)?
Aby zilustrować:

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

Otrzymaną offset jest, w tym przypadku, 5, ponieważ środowisko wykonawcze faktycznie porusza Field3 do końca typu (i podkładki IT), prawdopodobnie dlatego, że jej typ jest rodzajowy. Wiem, że istnieje Marshal.OffsetOf, ale zwraca niezarządzanego offset, nie zarządzany.

Jak mogę pobrać to przesunięcie z instancji FieldInfo? Czy jest do tego jakakolwiek metoda .NET, czy też muszę napisać własną, biorąc pod uwagę wszystkie wyjątki (rozmiar, wypełnienie, wyraźne przesunięcia itp.)?

+0

@usr Meant 'Field3'. Właściwie to jest zreformowane, ku mojemu zaskoczeniu. Przesunął to pole na koniec klasy, dopełniając go (debugowanie i wydanie, 32-bitowe). Może mieć coś wspólnego z niemożnością uzyskania wskaźników typów ogólnych. – IllidanS4

+1

Nie można się dowiedzieć, zarządzany układ obiektu jest szczegółem implementacji. Innym niż przez tylne drzwi, które już odkryłeś. CLR wykorzystuje to do zoptymalizowania układu, czyniąc obiekt tak małym, jak to możliwe, a jednocześnie zapewniając gwarancje wyrównania. [StructLayout] jest honorowany tylko na strukturach marshallowych. W takim przypadku Marshal.SizeOf() daje ci przesunięcie. –

+1

@Hans But Marshal.SizeOf zwraca rozmiar niezarządzanego typu, a nie zarządzany. Pomyślałem, że LayoutKind.Explicit jest honorowany na strukturach, ponieważ pokrywające się pola są tego dowodem, bez zestawiania. – IllidanS4

Odpowiedz

2

W przypadku niektórych sztuczek wokół TypedReference.MakeTypedReference możliwe jest uzyskanie odniesienia do pola i do początku danych obiektu, a następnie odjęcie. Metodę można znaleźć w SharpUtils.

Powiązane problemy