CÁC GIẢI PHÁP LẬP TRÌNH C# - Trang 592

592
Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý

System.Runtime.Interop.Marshal

nếu muốn xác định kích thước của cấu trúc

theo byte.

Trong mã C# thuần túy, bạn không có khả năng trực tiếp kiểm soát việc cấp bộ nhớ. Thay vào
đó, CRL sẽ quyết định khi nào cần đưa dữ liệu vào bộ nhớ để tối ưu hóa hoạt động. Điều này
gây rắc rối khi làm việc với các hàm C, vì cấu trúc phải được trữ liên tục trong bộ nhớ. May
mắn là .NET đã giải quyết vấn đề này bằng đặc tính

StructLayoutAttribute

, cho phép bạn chỉ

định các thành viên của một lớp hay một cấu trúc cho trước sẽ được sắp xếp trong bộ nhớ như
thế nào.
Ví dụ, xét hàm

GetVersionEx

trong thư viện kernel32.dll. Hàm này nhận một con trỏ chỉ tới

cấu trúc

OSVERSIONINFO

và sử dụng nó để trả về thông tin phiên bản của hệ điều hành. Để sử

dụng cấu trúc

OSVERSIONINFO

trong mã C#, bạn phải định nghĩa nó với đặc tính

StructLayoutAttribute

như sau:

[StructLayout(LayoutKind.Sequential)]

public class OSVersionInfo {

public int dwOSVersionInfoSize;

public int dwMajorVersion;

public int dwMinorVersion;

public int dwBuildNumber;

public int dwPlatformId;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]

public String szCSDVersion;

}

Chú ý rằng, cấu trúc này cũng sử dụng đặc tính

System.Runtime.InteropServices.

MarshalAsAttribute

(cần cho các chuỗi có kích thước không đổi). Ở đây,

MarshalAsAttribute

chỉ định chuỗi sẽ được truyền bằng trị và sẽ chứa một bộ đệm gồm 128

ký tự được chỉ định trong cấu trúc

OSVersionInfo

. Trong ví dụ này,

LayoutKind.Sequential

được sử dụng, nghĩa là các kiểu dữ liệu trong cấu trúc được bố trí theo thứ tự mà chúng được
liệt kê trong cấu trúc hoặc lớp.
Ngoài

LayoutKind.Sequential

, bạn có thể sử dụng

LayoutKind.Explicit

. Trong trường hợp

này, bạn phải sử dụng

FieldOffsetAttribute

để định nghĩa độ dời của các trường. Cách này

hữu ích khi bạn muốn lưu trữ các trường một cách linh động hơn, hoặc bạn muốn bỏ qua
(không sử dụng) trường nào đó. Ví dụ sau định nghĩa lớp

OSVersionInfo

với

LayoutKind.Explicit

.

[StructLayout(LayoutKind.Explicit)]

public class OSVersionInfo {

[FieldOffset(0)] public int dwOSVersionInfoSize;

Liên Kết Chia Sẽ

** Đây là liên kết chia sẻ bới cộng đồng người dùng, chúng tôi không chịu trách nhiệm gì về nội dung của các thông tin này. Nếu có liên kết nào không phù hợp xin hãy báo cho admin.