Presentation is loading. Please wait.

Presentation is loading. Please wait.

Advanced .NET Programming II 4th Lecture

Similar presentations


Presentation on theme: "Advanced .NET Programming II 4th Lecture"— Presentation transcript:

1 Advanced .NET Programming II 4th Lecture
Pavel Ježek Some of the slides are based on University of Linz .NET presentations. © University of Linz, Institute for System Software, 2004 published under the Microsoft Curriculum License (

2 CLI Type System All types Value types Reference types Pointers
(allocated in-place [with exceptions]) Reference types (allocated on managed heap) Pointers Structures Enumerations Classes Interfaces Arrays Delegates Simple types (Int32, Int64, Double, Boolean, Char, …) Nullables User defined structures

3 Pointer Types Examples Syntax int int pointers to arbitrary types
ip int int* ip; // pointer to an int cell MyStruct* sp; // pointer to a MyStruct object void* vp; // pointer to any memory location int** ipp; // pointer to a pointer to an int cell sp MyStruct vp ipp int PointerType = UnmanagedType * | void *. UnmanagedType = ValueType | PointerType. pointers to arbitrary types if a struct type, all fields must be of an UnmanagedType Syntax pointers are not traced by the garbage collector (referenced objects are not collected) pointer types are not compatible with System.Object pointer variables can have the value null pointers of different types can be compared with each other (==, !=, <, <=, >, >=)

4 Unsafe Code Code that works with pointers is potentially unsafe
(can break type rules and destroy arbitrary memory locations) must be enclosed in an unsafe block or an unsafe method unsafe { int* p; ... } unsafe void foo() { int* p; ... } must be compiled with the unsafe option csc -unsafe MyProg.cs system administrator must assign FullTrust rights to the program

5 Using Pointers Dereferencing a pointer Access to struct fields
var int var; int* ip = &var; ip *ip = 5; int x = *ip; if v is of type T*, *v is of type T void* cannot be dereferenced Access to struct fields struct Block { int x, y, z; } Block b; Block* bp = &b; bp->x = 1; // pointer notation (*bp).y = 2 // alternatively bp x y z bp must be of type Block* works also for method calls b Access to array elements int[] a = new int[3]; int* ap = a; ap[1] = 1; // array notation *(ap+1) = 2 // alternatively ap no index bound checks! ap[3] would be accepted a 1 2

6 Address Arithmetic Pointers can be used in calculations
T* p = ...; p T T p++; p--; // increases p by sizeof(T) p T* q, r; q = p + 2; r = p - 1; T p // q = p + 2*sizeof(T) // r = p - sizeof(T) r q No pointer arithmetic with void*

7 Type Casts On Pointers Implicit Casts Explicit Casts
int i; int* ip; Block* bp; void* vp; Implicit Casts (without cast operator) Explicit Casts (with cast operator) T1*  T2* ip = (int*)vp; vp = (void*)ip; bp = (Block*)vp; T*  intType ip = (int*)i; bp = (Block*)i; vp = (void*)i; i = (int)ip; i = (int)bp; i = (int)vp; unchecked! T*  null ip = null; bp = null; vp = null; void*  T* vp = ip; vp = bp;

8 Pinned and Unpinned Variables
cannot be moved by the garbage collector local variables value parameters fields of structs which are pinned themselves Unpinned can be moved by the garbage collector fields of classes (also static fields) array elements ref and out parameters

9 Adress Operator Note yields the address of designator
designator must denote a pinned variable (e.g. &x, &s.f) the type of the variable must not be managed (i.e. no class, no array) if designator is of type T, &designator is of type T*

10 fixed Statement Pins an unpinned variable during the execution of this statement (i.e. the garbage collector cannot move it during this statement) Syntax FixedStat = "fixed" "(" PointerType FixedVarDecl {"," FixedVarDecl} ")" Statement. FixedVarDecl = ident "=" ( "&" UnpinnedVar | ArrayVar | StringVar ). UnpinnedVar must be of an unmanaged type T T* must be assignable to PointerType array elements must be of an unmanaged type T T* must be asignable to PointerType char* must be assignable to PointerType Examples int field; int[] a = new int[10]; Person person = new Person(); string s = "Hello"; fixed (byte* p = &field) { Console.Write(*(p+1)); } fixed (int* p = &a[1]) {...} fixed (int* p = &person.id) {...} fixed (int* p = a) {...} fixed (char* p = s) {...} Variables that are declared in the header of a fixed statement are read-only

11 Examples Printing the bytes of an int variable String processing x
int x = 3; unsafe { byte* p = (byte*) &x; for (int i = 0; i < 4; i++) { Console.Write("{0:x2} ", *p); p++; } } 3 p String processing string s = "Hello"; unsafe { fixed (char* p = s) { for (int i = 0; p[i] != '\0'; i++) Console.Write(p[i]); } s H e l p o \0

12 Examples (continued) Overlaying a byte array with a struct type
struct Block { int x; float f; int y; } ... byte[] buffer = new byte[1024]; unsafe { fixed (byte* bp = &buffer[3]) { Block* b = (Block*) bp; Console.WriteLine(b->x + " " + b->f + " " + b->y); x f y buffer b

13 Dangers of Pointer Processing
Can destroy arbitrary memory locations int[] a = new int[3]; unsafe { fixed (int* p = a) { p[5] = 0; } } One can be left with pointers to objects that are moved by the garbage collector int[] a = new int[5]; int* p; unsafe { fixed (int* q = a) { p = q+2; } ... ... // GC can move array now *p = 5; // destroys data } p q a

14 Dangers of Pointer Processing (cont.)
One can be left with pointers to non-existing local variables static unsafe int* Foo() { int local = 3; return &local; } static unsafe void Main() { int* p = Foo(); ... *p = 5; // accesses non-existing local variable! Therefore Avoid pointer processing! Unless you really need it for system-level programming

15 StructLayout Attribute
using System.Runtime.InteropServices; [StructLayout(LayoutKind.Sequential, Pack=4)] // members are allocated sequentially class Time { // and are aligned at 4 byte boundaries public ushort year; public ushort month; ... } [StructLayout(LayoutKind.Explicit)] // members are allocated at specified offsets struct S { [FieldOffset(0)] ushort x; [FieldOffset(2)] int y;

16 StructLayout Attribute
[StructLayout ( layout-enum // Sequential | Explicit | Auto [, Pack=packing-size] // 0, 1, 2, 4, 8, 16, ... [, CharSet=charset-enum] // Ansi | Unicode | Auto )]

17 More Unsafe Features

18 IntPtr

19 Calling a Function from a Win32 DLL
Signature of the Win32 function int MessageBox (HWND hWnd, LPTSTR lpText, LPTSTR lpCaption, UINT uType); Invocation from C# using System; using System.Runtime.InteropServices; class Test { [DllImport("user32.dll")] static extern int MessageBox(uint hWnd, string text, string caption, uint type); // no body static void Main() { int res = MessageBox(0, "Isn't that cool?", "", 1); Console.WriteLine("res = " + res); }

20 DllImport Attribute [DllImport ( dll.name [, EntryPoint=function-name]
[, CharSet=charset-enum] // for string marshaling [, ExactSpelling= (true|false)] // should name be modified acc. to CharSet? [, SetLastError= (true|false)] // true: returns Win32 error info [, CallingConvention=callconv-enum] )] charset-enum: CharSet.Auto (default), CharSet.Ansi, CharSet.Unicode, ... callconv-enum: CallingConvention.StdCall (default), CallingConvention.FastCall, ...

21 Parameter Marshaling Primitive types of C# are automatically mapped to Win32 types. Standard mapping can be modified as follows: using System.Runtime.InteropServices; ... [DllImport("...")] static extern void Foo ( [MarshalAs(UnmanagedType.LPStr)] string s, int x ); LPStr ANSI string consisting of bytes LPWStr Unicode string LPTStr default: Windows XP/NT/2000 => Unicode, Windows 98 => ANSI


Download ppt "Advanced .NET Programming II 4th Lecture"

Similar presentations


Ads by Google