Các giải pháp lập trình CSharp- P71
Số trang: 10
Loại file: pdf
Dung lượng: 2.63 MB
Lượt xem: 3
Lượt tải: 0
Xem trước 2 trang đầu tiên của tài liệu này:
Thông tin tài liệu:
Các giải pháp lập trình CSharp- P71: Các giải pháp lập trình C# khảo sát chiều rộng của thư viện lớp .NET Framework và cung cấp giải pháp cụ thể cho các vấn đềthường gặp. Mỗi giải pháp được trình bày theo dạng “vấn đề/giải pháp” một cách ngắn gọn và kèm theo là các ví dụ mẫu.
Nội dung trích xuất từ tài liệu:
Các giải pháp lập trình CSharp- P71 591 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý private System.Windows.Forms.Label lblCaption; [DllImport(user32.dll)] private static extern int GetForegroundWindow(); [DllImport(user32.dll)] private static extern int GetWindowText(int hWnd, StringBuilder text, int count); private void tmrRefresh_Tick(object sender, System.EventArgs e) { int chars = 256; StringBuilder buff = new StringBuilder(chars); int handle = GetForegroundWindow(); if (GetWindowText(handle, buff, chars) > 0) { lblCaption.Text = buff.ToString(); lblHandle.Text = handle.ToString(); if (new IntPtr(handle) == this.Handle) { lblCurrent.Text = True; } else { lblCurrent.Text = False; } } }} Handle của form được quản lý một cách trong suốt đối với người dùng. Thay đổi thuộc tính nào đó của form có thể khiến cho CRL tạo một handle mới. Do đó, bạn nên luôn truy xuất handle ngay trước khi sử dụng nó (không nên giữ nó trong một biến để sử dụng trong một thời gian dài).3. Gọi một hàm không-được-quản-lý có sử dụng cấu trúc Bạn cần gọi một hàm không-được-quản-lý có thông số là một cấu trúc. Định nghĩa cấu trúc trong mã C#. Sử dụng đặc tính System.Runtime.InteropServices.StructLayoutAttribute để cấu hình việc cấp bộ nhớ cho cấu trúc. Sử dụng phương thức tĩnh SizeOf của lớp 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àygâ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ớ. Maymắ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ớicấ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ínhStructLayoutAttribute 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 128ký 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 đượcliệ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ợpnày, bạn phải sử dụng FieldOffsetAttribute để định nghĩa độ dời của các trường. Cách nàyhữ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ớiLayoutKind.Explicit.[StructLayout(LayoutKind.Explicit)]public class OSVersionInfo { [FieldOffset(0)] public int dwOSVersionInfoSize; 593 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý [FieldOffset(4)] public int dwMajorVersion; [FieldOffset(8)] public int dwMinorVersion; [FieldOffset(12)] public int dwBuildNumber; [FieldOffset(16)] public int dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] [FieldOffset(20)] public String szCSDVersion;}Sau khi đã định nghĩa cấu trúc được sử dụng bởi hàm GetVersionEx, bạn có thể khai báo hàmnày và sử dụng nó. Ứng dụng dưới đây sẽ trình bày toàn bộ mã lệnh cần thiết. Chú ý,InAttribute và OutAttribute được áp dụng cho OSVersionInfo để biết rằng marshalling sẽđược thực hiện trên cấu trúc này khi nó được truyền cho hàm và khi nó được trả về từ hàm.Ngoài ra, phương thức Marshal.SizeOf được sử dụng để tính kích thước của cấu trúc trong bộnhớ.using System;using System.Runtime.InteropServices;public class CallWithStructure { // (Bỏ qua lớp OSVersionInfo.) [DllImport(kernel32.dll)] public static extern bool GetVersionEx([In, Out] OSVersionInfo osvi); private static void Main() { OSVersionInfo osvi = new OSVersionInfo(); osvi.dwOSVersionInfoSize = Marshal.SizeOf(osvi); GetVersionEx(osvi); Console.WriteLine(Class size: + osvi.dwOSVersionInfoSize); Console.WriteLine(Major Version: + osvi.dwMajorVersion); Console.WriteLine(Minor Version: + osvi.dwMinorVersion); Console.WriteLine(Build Number: + osvi.dwBuildNumber); Console.WriteLine(Platform Id: + osvi.dwPlatformId); Console.WriteLine(CSD Version: + osvi.szCSDVersion); Console.WriteLine(Platform: + Environment.OSVersion.Platform); Console.WriteLine( Version: + Environment.OSVersion.Version); Console.ReadLine(); } 594 Chương 15: Khả năng liên tác mã lệnh không-được-q ...
Nội dung trích xuất từ tài liệu:
Các giải pháp lập trình CSharp- P71 591 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý private System.Windows.Forms.Label lblCaption; [DllImport(user32.dll)] private static extern int GetForegroundWindow(); [DllImport(user32.dll)] private static extern int GetWindowText(int hWnd, StringBuilder text, int count); private void tmrRefresh_Tick(object sender, System.EventArgs e) { int chars = 256; StringBuilder buff = new StringBuilder(chars); int handle = GetForegroundWindow(); if (GetWindowText(handle, buff, chars) > 0) { lblCaption.Text = buff.ToString(); lblHandle.Text = handle.ToString(); if (new IntPtr(handle) == this.Handle) { lblCurrent.Text = True; } else { lblCurrent.Text = False; } } }} Handle của form được quản lý một cách trong suốt đối với người dùng. Thay đổi thuộc tính nào đó của form có thể khiến cho CRL tạo một handle mới. Do đó, bạn nên luôn truy xuất handle ngay trước khi sử dụng nó (không nên giữ nó trong một biến để sử dụng trong một thời gian dài).3. Gọi một hàm không-được-quản-lý có sử dụng cấu trúc Bạn cần gọi một hàm không-được-quản-lý có thông số là một cấu trúc. Định nghĩa cấu trúc trong mã C#. Sử dụng đặc tính System.Runtime.InteropServices.StructLayoutAttribute để cấu hình việc cấp bộ nhớ cho cấu trúc. Sử dụng phương thức tĩnh SizeOf của lớp 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àygâ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ớ. Maymắ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ớicấ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ínhStructLayoutAttribute 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 128ký 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 đượcliệ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ợpnày, bạn phải sử dụng FieldOffsetAttribute để định nghĩa độ dời của các trường. Cách nàyhữ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ớiLayoutKind.Explicit.[StructLayout(LayoutKind.Explicit)]public class OSVersionInfo { [FieldOffset(0)] public int dwOSVersionInfoSize; 593 Chương 15: Khả năng liên tác mã lệnh không-được-quản-lý [FieldOffset(4)] public int dwMajorVersion; [FieldOffset(8)] public int dwMinorVersion; [FieldOffset(12)] public int dwBuildNumber; [FieldOffset(16)] public int dwPlatformId; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)] [FieldOffset(20)] public String szCSDVersion;}Sau khi đã định nghĩa cấu trúc được sử dụng bởi hàm GetVersionEx, bạn có thể khai báo hàmnày và sử dụng nó. Ứng dụng dưới đây sẽ trình bày toàn bộ mã lệnh cần thiết. Chú ý,InAttribute và OutAttribute được áp dụng cho OSVersionInfo để biết rằng marshalling sẽđược thực hiện trên cấu trúc này khi nó được truyền cho hàm và khi nó được trả về từ hàm.Ngoài ra, phương thức Marshal.SizeOf được sử dụng để tính kích thước của cấu trúc trong bộnhớ.using System;using System.Runtime.InteropServices;public class CallWithStructure { // (Bỏ qua lớp OSVersionInfo.) [DllImport(kernel32.dll)] public static extern bool GetVersionEx([In, Out] OSVersionInfo osvi); private static void Main() { OSVersionInfo osvi = new OSVersionInfo(); osvi.dwOSVersionInfoSize = Marshal.SizeOf(osvi); GetVersionEx(osvi); Console.WriteLine(Class size: + osvi.dwOSVersionInfoSize); Console.WriteLine(Major Version: + osvi.dwMajorVersion); Console.WriteLine(Minor Version: + osvi.dwMinorVersion); Console.WriteLine(Build Number: + osvi.dwBuildNumber); Console.WriteLine(Platform Id: + osvi.dwPlatformId); Console.WriteLine(CSD Version: + osvi.szCSDVersion); Console.WriteLine(Platform: + Environment.OSVersion.Platform); Console.WriteLine( Version: + Environment.OSVersion.Version); Console.ReadLine(); } 594 Chương 15: Khả năng liên tác mã lệnh không-được-q ...
Tìm kiếm theo từ khóa liên quan:
kinh nghiệm lập trình CSharp mẹo lập trình ngôn ngữ lập trình C giáo trình lập trình CSharp lập trình java lập trình căn bản CSharpGợi ý tài liệu liên quan:
-
Thủ thuật giúp giải phóng dung lượng ổ cứng
4 trang 210 0 0 -
NGÂN HÀNG CÂU HỎI TRẮC NGHIỆM THIẾT KẾ WEB
8 trang 202 0 0 -
101 trang 199 1 0
-
Tìm hiểu về ngôn ngữ lập trình C: Phần 1 - Quách Tuấn Ngọc
211 trang 149 0 0 -
142 trang 129 0 0
-
161 trang 129 1 0
-
Giáo trình Vi điều khiển PIC: Phần 1
119 trang 116 0 0 -
Bài giảng Phương pháp lập trình: Chương 9 - GV. Từ Thị Xuân Hiền
36 trang 109 0 0 -
Excel add in development in c and c phần 9
0 trang 107 0 0 -
78 trang 101 0 0