Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 1
Số trang: 11
Loại file: pdf
Dung lượng: 119.79 KB
Lượt xem: 12
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ó những trường hợp ta cần truy xuất bộ nhớ trực tiếp khi ta muốn truy xuất vào các hàm bên ngoài ( không thuộc .NET) mà đòi hỏi con trỏ được truyền vào như tham số( ví dụ như các hàm API ).hoặc là vì ta muốn truy nhập vào nội dung bộ nhớ để sửa lỗi....Trong phần này ta sẽ xem xét cách C# đáp ứng những điều này như thế nào. Con trỏ ( trình bày vắng tắt )
Nội dung trích xuất từ tài liệu:
Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 1 Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 1Có những trường hợp ta cần truy xuất bộ nhớ trực tiếp khi ta muốn truy xuấtvào các hàm bên ngoài ( không thuộc .NET) mà đòi hỏi con trỏ được truyềnvào như tham số( ví dụ như các hàm API ).hoặc là vì ta muốn truy nhập vàonội dung bộ nhớ để sửa lỗi....Trong phần này ta sẽ xem xét cách C# đáp ứngnhững điều này như thế nào.Con trỏ( trình bày vắng tắt )Con trỏ đơn giản là 1 biến lưu địa chỉ của một thứ khác theo cùng 1 cáchnhư là 1 tham chiếu. sự khác biệt là cú pháp C# trong tham chiếu không chophép ta truy xuất vào địa chỉ bộ nhớ.3 ưu điểm của con trỏ : Cải thiện sự thực thi : cho ta biết những gì ta đang làm,đảm bảo rằngdữ liệu được truy xuất hay thao tác theo cách hiệu quả nhất - đó là lí do màC và C++ cho phép dung con trỏ trong ngôn ngữ của mình. Khả năng tích hợp với các phần trước ( Backward compatibility ) - đôikhi ta phải sử dụng lại các hàm API cho mục đích của ta.Mà các hàm APIđược viết bằng C,ngôn ngữ dùng con trỏ rất nhiều, nghĩa là nhiều hàm lấycon trỏ như tham số.Hoặc là các DLL do 1 hãng nào đó cung cấp chứa cáchàm lấy con trỏ làm tham số . Trong nhiều trường hợp ta có thể viết cáckhai báo DLlImport theo cách tránh sử dụng con trỏ , ví dụ như dùng lớpSystem.IntPtr. Ta có thể cần tạo ra các địa chỉ vùng nhớ có giá trị cho người dùng -ví dụ nếu ta muốn phát triển 1 ứng dụng mà cho phép người dùng tương táctrực tiếp đến bộ nhớ, như là 1 debugger.Nhược điểm : Cú pháp để lấy các hàm phức tạp hơn Con trỏ khó sử dụng Nếu không cẩn thận ta có thể viết lên các biến khác ,làm tràn stack,mất thông tin, đụng độ ... C# có thể từ chối thi hành những đoạn mã không an toàn này (đoạnmã có sử dụng con trỏ)Ta có thể đánh dấu đoạn mã có sử dụng con trỏ bằng cách dùng từ khoáunsafeVí dụ : dùng cho hàmunsafe int GetSomeNumber(){ // code that can use pointers}Dùng cho lớp hay structunsafe class MyClass{ // any method in this class can now use pointers}Dùng cho 1 trườngclass MyClass{ unsafe int *pX; // declaration of a pointer field in a class}Hoặc một khối mãvoid MyMethod(){ // code that doesnt use pointers unsafe { // unsafe code that uses pointers here } // more safe code that doesnt use pointers}Tuy nhiên ta không thể đánh dấu 1 biến cục bộ là unsafeint MyMethod(){ unsafe int *pX; // WRONG}Để biên dịch các mã chứa khối unsafe ta dùng lệnh sau :csc /unsafe MySource.cshaycsc -unsafe MySource.csCú pháp con trỏint * pWidth, pHeight;double *pResult;Lưu ý khác với C++ ,kí tự * kết hợp với kiểu hơn là kết hợp với biến - nghĩalà khi ta khai báo như ở trên thì pWidth và pHeight đều là con trỏ do có *sau kiểu int, khác với C++ ta phải khai báo * cho cả hai biến trên thì cả haimới là con trỏ.Cách dùng * và & giống như trong C++ :& : lấy địa chỉ* : lấy nội dung của địa chỉÉp kiểu con trỏ thành kiểu IntVì con trỏ là 1 số int lưu địa chỉ nên ta có thể chuyển tường minh con trỏthành kiểu int hay ngược lại.Ví dụ:int x = 10;int *pX, pY;pX = &x;pY = pX;*pY = 20;uint y = (uint)pX;int *pD = (int*)y;y là uint.sau đó ta chuyển ngược lại thành biến con trỏ pD1 lý do để ta phải ép kiểu là Console.WriteLine không có overload nào nhậnthông số là con trỏ do đó ta phải ép nó sang kiểu số nguyên intConsole.WriteLine(Address is + pX); // wrong - will give a // compilation errorConsole.WriteLine(Address is + (uint) pX); // OKÉp kiểu giữa những kiểu con trỏTa cũng có thể chuyển đổi tường minh giữa các con trỏ trỏ đến1 kiểu khác vídụ :byte aByte = 8;byte *pByte= &aByte;double *pDouble = (double*)pByte;void PointersNếu ta muốn giữ 1 con trỏ , nhưng không muốn đặc tả kiểu cho con trỏ ta cóthể khai báo co ntrỏ là void:void *pointerToVoid;pointerToVoid = (void*)pointerToInt; // pointerToInt declared as int*mục đích là khi ta cần gọi các hàm API mà đòi hỏi thông số void*.Toán tử sizeofLấy thông số là tên của kiểu và trả về số byte của kiểu đó ví dụ :int x = sizeof(double);x có giá trị là 8Bảng kích thước kiểu :sizeof(sbyte) = 1; sizeof(byte) = 1;sizeof(short) = 2; sizeof(ushort) = 2;sizeof(int) = 4; sizeof(uint) = 4;sizeof(long) = 8; sizeof(ulong) = 8;sizeof(char) = 2; sizeof(float) = 4;sizeof(double) = 8; sizeof(bool) = 1;Ta cũng có thể dùng sizeof cho struct nhưng không dùng được cho lớp.Ví dụ PointerPlayaroundVí dụ sau trình bày cách thao tác trên con trỏ và trình bày kết quả, cho phépta thấy những gì xảy ra trong bộ nhớ và nơi biến được lưu trữ:using System;namespace Wrox.ProCSharp.AdvancedCSharp{ ...
Nội dung trích xuất từ tài liệu:
Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 1 Những chủ đề tiến bộ trong C# Các mã không an toàn – Phần 1Có những trường hợp ta cần truy xuất bộ nhớ trực tiếp khi ta muốn truy xuấtvào các hàm bên ngoài ( không thuộc .NET) mà đòi hỏi con trỏ được truyềnvào như tham số( ví dụ như các hàm API ).hoặc là vì ta muốn truy nhập vàonội dung bộ nhớ để sửa lỗi....Trong phần này ta sẽ xem xét cách C# đáp ứngnhững điều này như thế nào.Con trỏ( trình bày vắng tắt )Con trỏ đơn giản là 1 biến lưu địa chỉ của một thứ khác theo cùng 1 cáchnhư là 1 tham chiếu. sự khác biệt là cú pháp C# trong tham chiếu không chophép ta truy xuất vào địa chỉ bộ nhớ.3 ưu điểm của con trỏ : Cải thiện sự thực thi : cho ta biết những gì ta đang làm,đảm bảo rằngdữ liệu được truy xuất hay thao tác theo cách hiệu quả nhất - đó là lí do màC và C++ cho phép dung con trỏ trong ngôn ngữ của mình. Khả năng tích hợp với các phần trước ( Backward compatibility ) - đôikhi ta phải sử dụng lại các hàm API cho mục đích của ta.Mà các hàm APIđược viết bằng C,ngôn ngữ dùng con trỏ rất nhiều, nghĩa là nhiều hàm lấycon trỏ như tham số.Hoặc là các DLL do 1 hãng nào đó cung cấp chứa cáchàm lấy con trỏ làm tham số . Trong nhiều trường hợp ta có thể viết cáckhai báo DLlImport theo cách tránh sử dụng con trỏ , ví dụ như dùng lớpSystem.IntPtr. Ta có thể cần tạo ra các địa chỉ vùng nhớ có giá trị cho người dùng -ví dụ nếu ta muốn phát triển 1 ứng dụng mà cho phép người dùng tương táctrực tiếp đến bộ nhớ, như là 1 debugger.Nhược điểm : Cú pháp để lấy các hàm phức tạp hơn Con trỏ khó sử dụng Nếu không cẩn thận ta có thể viết lên các biến khác ,làm tràn stack,mất thông tin, đụng độ ... C# có thể từ chối thi hành những đoạn mã không an toàn này (đoạnmã có sử dụng con trỏ)Ta có thể đánh dấu đoạn mã có sử dụng con trỏ bằng cách dùng từ khoáunsafeVí dụ : dùng cho hàmunsafe int GetSomeNumber(){ // code that can use pointers}Dùng cho lớp hay structunsafe class MyClass{ // any method in this class can now use pointers}Dùng cho 1 trườngclass MyClass{ unsafe int *pX; // declaration of a pointer field in a class}Hoặc một khối mãvoid MyMethod(){ // code that doesnt use pointers unsafe { // unsafe code that uses pointers here } // more safe code that doesnt use pointers}Tuy nhiên ta không thể đánh dấu 1 biến cục bộ là unsafeint MyMethod(){ unsafe int *pX; // WRONG}Để biên dịch các mã chứa khối unsafe ta dùng lệnh sau :csc /unsafe MySource.cshaycsc -unsafe MySource.csCú pháp con trỏint * pWidth, pHeight;double *pResult;Lưu ý khác với C++ ,kí tự * kết hợp với kiểu hơn là kết hợp với biến - nghĩalà khi ta khai báo như ở trên thì pWidth và pHeight đều là con trỏ do có *sau kiểu int, khác với C++ ta phải khai báo * cho cả hai biến trên thì cả haimới là con trỏ.Cách dùng * và & giống như trong C++ :& : lấy địa chỉ* : lấy nội dung của địa chỉÉp kiểu con trỏ thành kiểu IntVì con trỏ là 1 số int lưu địa chỉ nên ta có thể chuyển tường minh con trỏthành kiểu int hay ngược lại.Ví dụ:int x = 10;int *pX, pY;pX = &x;pY = pX;*pY = 20;uint y = (uint)pX;int *pD = (int*)y;y là uint.sau đó ta chuyển ngược lại thành biến con trỏ pD1 lý do để ta phải ép kiểu là Console.WriteLine không có overload nào nhậnthông số là con trỏ do đó ta phải ép nó sang kiểu số nguyên intConsole.WriteLine(Address is + pX); // wrong - will give a // compilation errorConsole.WriteLine(Address is + (uint) pX); // OKÉp kiểu giữa những kiểu con trỏTa cũng có thể chuyển đổi tường minh giữa các con trỏ trỏ đến1 kiểu khác vídụ :byte aByte = 8;byte *pByte= &aByte;double *pDouble = (double*)pByte;void PointersNếu ta muốn giữ 1 con trỏ , nhưng không muốn đặc tả kiểu cho con trỏ ta cóthể khai báo co ntrỏ là void:void *pointerToVoid;pointerToVoid = (void*)pointerToInt; // pointerToInt declared as int*mục đích là khi ta cần gọi các hàm API mà đòi hỏi thông số void*.Toán tử sizeofLấy thông số là tên của kiểu và trả về số byte của kiểu đó ví dụ :int x = sizeof(double);x có giá trị là 8Bảng kích thước kiểu :sizeof(sbyte) = 1; sizeof(byte) = 1;sizeof(short) = 2; sizeof(ushort) = 2;sizeof(int) = 4; sizeof(uint) = 4;sizeof(long) = 8; sizeof(ulong) = 8;sizeof(char) = 2; sizeof(float) = 4;sizeof(double) = 8; sizeof(bool) = 1;Ta cũng có thể dùng sizeof cho struct nhưng không dùng được cho lớp.Ví dụ PointerPlayaroundVí dụ sau trình bày cách thao tác trên con trỏ và trình bày kết quả, cho phépta thấy những gì xảy ra trong bộ nhớ và nơi biến được lưu trữ:using System;namespace Wrox.ProCSharp.AdvancedCSharp{ ...
Tìm kiếm theo từ khóa liên quan:
lập trình tài liệu lập trình kỹ thuật lập trình giáo trình C ngôn ngữ lập trình C tự học lập trình với CTài liệu có liên quan:
-
Kỹ thuật lập trình trên Visual Basic 2005
148 trang 309 0 0 -
NGÂN HÀNG CÂU HỎI TRẮC NGHIỆM THIẾT KẾ WEB
8 trang 248 0 0 -
Giới thiệu môn học Ngôn ngữ lập trình C++
5 trang 222 0 0 -
101 trang 211 1 0
-
Bài giảng Nhập môn về lập trình - Chương 1: Giới thiệu về máy tính và lập trình
30 trang 188 0 0 -
Luận văn: Nghiên cứu kỹ thuật giấu tin trong ảnh Gif
33 trang 159 0 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 154 0 0 -
Giáo trình Lập trình C căn bản - HanoiAptech Computer Education Center
136 trang 143 0 0 -
161 trang 139 1 0
-
Giáo trình Vi điều khiển PIC: Phần 1
119 trang 131 0 0