/*
A Programmer's Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress L.P.
ISBN: 1-893115-62-3
*/
// 31 - InteropCalling Native DLL FunctionsPointers 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));
}
}
}
Language Basics
Unsafe code: copy
/*
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} ", x, arr1[x]);
Console.Write ("arr2[{0}] = {1}
", 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++;
}
}
}
}
}
[/csharp]
Multiple Indirect
/*
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
}
}
Use fixed to get a pointer to the start of a string
/*
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();
}
}
Index a pointer as if it were an array
/*
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("
Use 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));
}
}
}
[/csharp]
An array name with an index yields a pointer to the start of the array
/*
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.");
}
}
}
Demonstrate pointer comparison
/*
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);
}
}
[/csharp]