Csharp/C Sharp/Language Basics/Pointer Unsafe — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Версия 18:31, 26 мая 2010
Содержание
- 1 An array name with an index yields a pointer to the start of the array
- 2 Demonstrate fixed
- 3 Demonstrate pointer comparison
- 4 Demonstrate pointers and unsafe
- 5 Demonstrate the effects of pointer arithmethic
- 6 Index a pointer as if it were an array
- 7 Multiple Indirect
- 8 Pointers and Declarative Pinning
- 9 References and Pointers
- 10 Unsafe code: copy
- 11 Unsafe Context
- 12 Use fixed to get a pointer to the start of a string
An array name with an index yields a pointer to the start of the array
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
/* An array name with an index yields a pointer to the
start of the array. */
using System;
public class PtrArray {
unsafe public static void Main() { int[] nums = new int[10]; fixed(int* p = &nums[0], p2 = nums) { if(p == p2) Console.WriteLine("p and p2 point to same address."); } }
}
</source>
Demonstrate fixed
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Demonstrate fixed.
using System;
class Test {
public int num; public Test(int i) { num = i; }
}
public class FixedCode {
// mark Main as unsafe unsafe public static void Main() { Test o = new Test(19); fixed (int* p = &o.num) { // use fixed to put address of o.num into p Console.WriteLine("Initial value of o.num is " + *p); *p = 10; // assign the to count via p Console.WriteLine("New value of o.num is " + *p); } }
}
</source>
Demonstrate pointer comparison
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Demonstrate pointer comparison.
using System;
public class PtrCompDemo {
unsafe public static void Main() { int[] nums = new int[11]; int x; // find the middle fixed (int* start = &nums[0]) { fixed(int* end = &nums[nums.Length-1]) { for(x=0; start+x <= end-x; x++) ; } } Console.WriteLine("Middle element is " + x); }
}
</source>
Demonstrate pointers and unsafe
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Demonstrate pointers and unsafe.
using System;
public class UnsafeCode {
// mark Main as unsafe unsafe public static void Main() { int count = 99; int* p; // create an int pointer p = &count; // put address of count into p Console.WriteLine("Initial value of count is " + *p); *p = 10; // assign the to count via p Console.WriteLine("New value of count is " + *p); }
}
</source>
Demonstrate the effects of pointer arithmethic
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Demonstrate the effects of pointer arithmethic.
using System;
public class PtrArithDemo {
unsafe public static void Main() { int x; int i; double d; int* ip = &i; double* fp = &d; Console.WriteLine("int double\n"); for(x=0; x < 10; x++) { Console.WriteLine((uint) (ip) + " " + (uint) (fp)); ip++; fp++; } }
}
</source>
Index a pointer as if it were an array
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Index a pointer as if it were an array.
using System;
public class PtrIndexDemo {
unsafe public static void Main() { int[] nums = new int[10]; // index pointer Console.WriteLine("Index pointer like array."); fixed (int* p = nums) { for(int i=0; i < 10; i++) p[i] = i; // index pointer like array for(int i=0; i < 10; i++) Console.WriteLine("p[{0}]: {1} ", i, p[i]); } // use pointer arithmetic Console.WriteLine("\nUse pointer arithmetic."); fixed (int* p = nums) { for(int i=0; i < 10; i++) *(p+i) = i; // use pointer arithmetic for(int i=0; i < 10; i++) Console.WriteLine("*(p+{0}): {1} ", i, *(p+i)); } }
}
</source>
Multiple Indirect
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
using System;
public class MultipleIndirect {
unsafe public static void Main() { int x; // holds a int value int* p; // holds an int pointer int** q; // holds an pointer to an int pointer x = 10; p = &x; // put address of x into p q = &p; // put address of p into q Console.WriteLine(**q); // display the value of x }
}
</source>
Pointers and Declarative Pinning
<source lang="csharp"> /* A Programmer"s Introduction to C# (Second Edition) by Eric Gunnerson Publisher: Apress L.P. ISBN: 1-893115-62-3
- /
// 31 - Interop\Calling Native DLL Functions\Pointers and Declarative Pinning // copyright 2000 Eric Gunnerson // file=ReadFileUnsafe.cs // compile with: csc /unsafe ReadFileUnsafe.cs using System; using System.Runtime.InteropServices; using System.Text; class FileRead {
const uint GENERIC_READ = 0x80000000; const uint OPEN_EXISTING = 3; int handle; public FileRead(string filename) { // opens the existing file handle = CreateFile( filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0); } [DllImport("kernel32", SetLastError=true)] static extern int CreateFile( string filename, uint desiredAccess, uint shareMode, uint attributes, // really SecurityAttributes pointer uint creationDisposition, uint flagsAndAttributes, uint templateFile); [DllImport("kernel32", SetLastError=true)] static extern unsafe bool ReadFile( int hFile, void* lpBuffer, int nBytesToRead, int* nBytesRead, int overlapped); public unsafe int Read(byte[] buffer, int count) { int n = 0; fixed (byte* p = buffer) { ReadFile(handle, p, count, &n, 0); } return n; }
} public class PointersandDeclarativePinning {
public static void Main(string[] args) { FileRead fr = new FileRead(args[0]); byte[] buffer = new byte[128]; ASCIIEncoding e = new ASCIIEncoding(); // loop through, read until done Console.WriteLine("Contents"); while (fr.Read(buffer, 128) != 0) { Console.Write("{0}", e.GetString(buffer)); } }
}
</source>
References and Pointers
<source lang="csharp"> /*
* C# Programmers Pocket Consultant * Author: Gregory S. MacBeth * Email: gmacbeth@comporium.net * Create Date: June 27, 2003 * Last Modified Date: */
using System; using System.Runtime.InteropServices; namespace Client.Chapter_7___References__Pointers_and_Memory_Management {
public class ReferencesandPointers { static void Main(string[] args) { UsePointers(); } static unsafe public void UsePointers() { char * pMyArray = (char*)Marshal.AllocCoTaskMem(6); while (*pMyArray != "\0") { Console.WriteLine(*pMyArray); pMyArray++; } Marshal.FreeCoTaskMem((IntPtr)pMyArray); } }
}
</source>
Unsafe code: copy
<source lang="csharp"> /* C# Programming Tips & Techniques by Charles Wright, Kris Jamsa Publisher: Osborne/McGraw-Hill (December 28, 2001) ISBN: 0072193794
- /
namespace nsType {
using System; public class IntCopy { public static void Main () { int [] arr1 = new int[] {1, 4, 2, 8, 5, 7}; int [] arr2 = new int[arr1.Length]; MemCpy (arr2, arr1, arr1.Length); arr1[0] = 142857; for (int x = 0; x < arr1.Length; ++x) { Console.Write ("arr1[{0}] = {1}\t", x, arr1[x]); Console.Write ("arr2[{0}] = {1}\n", x, arr2[x]); } } static unsafe public void MemCpy (int [] dst, int [] src, int size) { if ((size > dst.Length) || (size > src.Length)) { ArgumentException e = new ArgumentException("The size argument is too large for one of the array arguments"); throw (e); } fixed (int *Src = src, Dst = dst) { int* pSrc = Src; int* pDst = Dst; for (int n = 0; n < size; ++n) { *pDst++ = *pSrc++; } } } }
}
</source>
Unsafe Context
<source lang="csharp"> /* A Programmer"s Introduction to C# (Second Edition) by Eric Gunnerson Publisher: Apress L.P. ISBN: 1-893115-62-3
- /
// 36 - Deeper into C#\Unsafe Context // copyright 2000 Eric Gunnerson // file=unsafe.cs // compile with: csc /unsafe /o+ unsafe.cs using System; using System.Diagnostics; using System.Runtime.InteropServices;
public class UnsafeContext {
const int iterations = 20000; // # to do copy const int points = 1000; // # of points in array const int retryCount = 5; // # of times to retry public delegate Point[] CloneFunction(Point[] a); public static void TimeFunction(Point[] arr, CloneFunction func, string label) { Point[] arrCopy = null; long start; long delta; double min = 5000.0d; // big number; // do the whole copy retryCount times, find fastest time for (int retry = 0; retry < retryCount; retry++) { start = Counter.Value; for (int iterate = 0; iterate < iterations; iterate++) arrCopy = func(arr); delta = Counter.Value - start; double result = (double) delta / Counter.Frequency; if (result < min) min = result; } Console.WriteLine("{0}: {1:F3} seconds", label, min); } public static void Main() { Console.WriteLine("Points, Iterations: {0} {1}", points, iterations); Point[] arr = new Point[points]; for (int index = 0; index < points; index++) arr[index] = new Point(3, 5); TimeFunction(arr, new CloneFunction(Point.ClonePointArrayMemcpy), "Memcpy"); TimeFunction(arr, new CloneFunction(Point.ClonePointArrayUnsafe), "Unsafe"); TimeFunction(arr, new CloneFunction(Point.ClonePointArray), "Baseline"); }
} class Counter {
public static long Frequency { get { long freq = 0; QueryPerformanceFrequency(ref freq); return freq; } } public static long Value { get { long count = 0; QueryPerformanceCounter(ref count); return count; } } [System.Runtime.InteropServices.DllImport("KERNEL32", CharSet=System.Runtime.InteropServices.CharSet.Auto)] private static extern bool QueryPerformanceCounter( ref long lpPerformanceCount); [System.Runtime.InteropServices.DllImport("KERNEL32", CharSet=System.Runtime.InteropServices.CharSet.Auto)] private static extern bool QueryPerformanceFrequency( ref long lpFrequency);
} public struct Point {
public Point(int x, int y) { this.x = x; this.y = y; } // safe version public static Point[] ClonePointArray(Point[] a) { Point[] ret = new Point[a.Length]; for (int index = 0; index < a.Length; index++) ret[index] = a[index]; return(ret); } // unsafe version using pointer arithmetic unsafe public static Point[] ClonePointArrayUnsafe(Point[] a) { Point[] ret = new Point[a.Length]; // a and ret are pinned; they cannot be moved by // the garbage collector inside the fixed block. fixed (Point* src = a, dest = ret) { Point* pSrc = src; Point* pDest = dest; for (int index = 0; index < a.Length; index++) { *pDest = *pSrc; pSrc++; pDest++; } } return(ret); } // import CopyMemory from kernel32 [DllImport("kernel32.dll")] unsafe public static extern void CopyMemory(void* dest, void* src, int length); // unsafe version calling CopyMemory() unsafe public static Point[] ClonePointArrayMemcpy(Point[] a) { Point[] ret = new Point[a.Length]; fixed (Point* src = a, dest = ret) { CopyMemory(dest, src, a.Length * sizeof(Point)); } return(ret); } public override string ToString() { return(String.Format("({0}, {1})", x, y)); } int x; int y;
}
</source>
Use fixed to get a pointer to the start of a string
<source lang="csharp"> /* C#: The Complete Reference by Herbert Schildt Publisher: Osborne/McGraw-Hill (March 8, 2002) ISBN: 0072134852
- /
// Use fixed to get a pointer to the start of a string.
using System;
public class FixedString {
unsafe public static void Main() { string str = "this is a test"; // Point p to start of str. fixed(char* p = str) { // Display the contents of str via p. for(int i=0; p[i] != 0; i++) Console.Write(p[i]); } Console.WriteLine(); }
}
</source>