2015-06-13 15 views
5

Tôi có lớp sau đây:Lấy lĩnh vực phi rõ ràng bù đắp

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

Làm thế nào tôi có thể nhận được các byte offset của Field4 bắt đầu từ sự bắt đầu của dữ liệu lớp (hoặc tiêu đề đối tượng)?
Để minh họa:

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

kết quả bù đắp, trong trường hợp này, 5, bởi vì thời gian chạy thực sự di chuyển Field3 đến hết loại (và miếng đệm nó), có lẽ bởi vì nó loại của nó là chung chung. Tôi biết có Marshal.OffsetOf, nhưng nó trả về bù đắp không được quản lý, không được quản lý.

Làm cách nào tôi có thể truy xuất chênh lệch này từ cá thể FieldInfo? Có phương pháp .NET nào được sử dụng cho điều đó không, hoặc tôi có phải viết riêng của mình, lấy tất cả các ngoại lệ vào tài khoản (loại kích thước, đệm, bù đắp rõ ràng, v.v.) không?

+0

@usr Có nghĩa là 'Field3'. Trên thực tế, nó được sắp xếp lại, với sự ngạc nhiên của tôi. Nó di chuyển trường đó đến cuối lớp, đệm nó (gỡ lỗi và phát hành, 32-bit). Nó có thể có một cái gì đó để làm với không có khả năng để có được con trỏ của các loại chung chung. – IllidanS4

+1

Bạn không thể tìm ra, bố cục đối tượng được quản lý là chi tiết triển khai. Khác hơn là thông qua backdoor bạn đã phát hiện ra. CLR sử dụng điều này để tối ưu hóa bố cục, làm cho đối tượng càng nhỏ càng tốt trong khi vẫn đảm bảo sự liên kết. [StructLayout] chỉ được vinh danh trên các cấu trúc marshaled. Trong trường hợp đó Marshal.SizeOf() cho bạn giá trị offset. –

+1

@Hans Nhưng Marshal.SizeOf trả về kích thước không được quản lý, không phải kích thước được quản lý. Tôi nghĩ LayoutKind.Explicit được vinh danh trên các cấu trúc, các trường chồng chéo là bằng chứng của nó, mà không cần marshalling. – IllidanS4

Trả lời

2

Với một số thủ thuật xung quanh TypedReference.MakeTypedReference, nó có thể để có được những tài liệu tham khảo để lĩnh vực này, và khi bắt đầu dữ liệu của đối tượng, sau đó chỉ cần trừ. Phương pháp này có thể được tìm thấy trong SharpUtils.

Các vấn đề liên quan