public class MyValue
{
public int id;
public MyValue(int id) { this.id = id; }
}
class UnsafeClassApp
{
unsafe public static void Swap(int* pi, int* pj)
{
int tmp = *pi;
*pi = *pj;
*pj = tmp;
}
static void Main(string[] args)
{
MyValue i = new MyValue(123);
MyValue j = new MyValue(456);
Console.WriteLine("Before Swap: i = {0}, j = {1}", i.id, j.id);
unsafe
{
(int* pi = &i.id, pj = &j.id)
{
Swap(pi, pj);
}
}
Console.WriteLine(
"After Swap: i = {0}, j = {1}", i.id, j.id);
}
}
Language Basics
Use unsafe method to clone array
public struct MyValue
{
public int id;
public MyValue(int id) { this.id = id; }
}
class ClassAddressApp
{
unsafe public static MyValue[] CloneMyValues(MyValue[] box)
{
MyValue[] ret = new MyValue[box.Length];
fixed (MyValue* src = box, dest = ret)
{
MyValue* pSrc = src;
MyValue* pDest = dest;
for (int index = 0; index < box.Length; index++)
{
*pDest = *pSrc;
pSrc++;
pDest++;
}
}
return ret;
}
static void Main(string[] args)
{
MyValue[] box = new MyValue[2];
box[0] = new MyValue(1);
box[1] = new MyValue(2);
MyValue[] bag = CloneMyValues(box);
foreach (MyValue i in bag)
{
Console.WriteLine(i.id);
}
}
}
[/csharp]
object pointer
using System;
public struct MyValue
{
public int id;
private decimal price;
public MyValue(int id, decimal price)
{
this.id = id;
this.price = price;
}
public void Foo() { Console.WriteLine("Foo"); }
}
class DerefMemberApp
{
static void Main(string[] args)
{
MyValue i = new MyValue(123, 45.67m);
unsafe
{
MyValue* pi = &i;
(*pi).Foo();
pi->Foo();
Console.WriteLine("id = {0}", pi->id);
}
}
}
Using the unsafe keyword
using System;
class Test {
public static unsafe String UnsafeCodeExample( String s ) {
int strLength = s.Length;
char[] str = new char[strLength+1];
string strReturn = “”;
fixed(char* strPointer = str) {
for ( int i=0; i
Address and size of pointer object
using System;
class MainEntryPoint {
static unsafe void Main() {
int x = 10;
short y = -1;
byte y2 = 4;
double z = 1.5;
int* pX = &x;
short* pY = &y;
double* pZ = &z;
Console.WriteLine("Address of x is 0x{0:X}, size is {1}, value is {2}",(uint)&x, sizeof(int), x);
Console.WriteLine(
"Address of y is 0x{0:X}, size is {1}, value is {2}",
(uint)&y, sizeof(short), y);
Console.WriteLine(
"Address of y2 is 0x{0:X}, size is {1}, value is {2}",
(uint)&y2, sizeof(byte), y2);
Console.WriteLine(
"Address of z is 0x{0:X}, size is {1}, value is {2}",
(uint)&z, sizeof(double), z);
Console.WriteLine(
"Address of pX=&x is 0x{0:X}, size is {1}, value is 0x{2:X}",
(uint)&pX, sizeof(int*), (uint)pX);
Console.WriteLine(
"Address of pY=&y is 0x{0:X}, size is {1}, value is 0x{2:X}",
(uint)&pY, sizeof(short*), (uint)pY);
Console.WriteLine(
"Address of pZ=&z is 0x{0:X}, size is {1}, value is 0x{2:X}",
(uint)&pZ, sizeof(double*), (uint)pZ);
*pX = 20;
Console.WriteLine("After setting *pX, x = {0}", x);
Console.WriteLine("*pX = {0}", *pX);
pZ = (double*)pX;
Console.WriteLine("x treated as a double = {0}", *pZ);
Console.ReadLine();
}
}
Unsafe code: get data type size
using System;
class MainEntryPoint
{
static unsafe void Main()
{
int x=100;
short y = -19;
byte y2 = 45;
double z = 31.5;
int *pX = &x;
short *pY = &y;
double *pZ = &z;
Console.WriteLine("Address of x is 0x{0:X}, size is {1}, value is {2}", (uint)&x, sizeof(int), x);
Console.WriteLine("Address of y is 0x{0:X}, size is {1}, value is {2}", (uint)&y, sizeof(short), y);
Console.WriteLine("Address of y2 is 0x{0:X}, size is {1}, value is {2}",(uint)&y2, sizeof(byte), y2);
Console.WriteLine("Address of z is 0x{0:X}, size is {1}, value is {2}", (uint)&z, sizeof(double), z);
Console.WriteLine("Address of pX=&x is 0x{0:X}, size is {1}, value is 0x{2:X}",(uint)&pX, sizeof(int*), (uint)pX);
Console.WriteLine("Address of pY=&y is 0x{0:X}, size is {1}, value is 0x{2:X}",(uint)&pY, sizeof(short*), (uint)pY);
Console.WriteLine("Address of pZ=&z is 0x{0:X}, size is {1}, value is 0x{2:X}",(uint)&pZ, sizeof(double*), (uint)pZ);
*pX = 20;
Console.WriteLine("After setting *pX, x = {0}", x);
Console.WriteLine("*pX = {0}", *pX);
pZ = (double*)pX;
Console.WriteLine("x treated as a double = {0}", *pZ);
}
}
Get variable address in unsafe mode
using System;
public class MainEntryPoint {
public static unsafe void Main() {
Console.WriteLine("Size of Currency struct is " + sizeof(MyStruct));
MyStruct amount1, amount2;
MyStruct* pointerStruct = &amount1;
long* pDollars = &(pointerStruct->Dollars);
byte* pCents = &(pointerStruct->Cents);
Console.WriteLine("Address of amount1 is 0x{0:X}", (uint)&amount1);
Console.WriteLine("Address of amount2 is 0x{0:X}", (uint)&amount2);
Console.WriteLine("Address of pAmt is 0x{0:X}", (uint)&pointerStruct);
Console.WriteLine("Address of pDollars is 0x{0:X}", (uint)&pDollars);
Console.WriteLine("Address of pCents is 0x{0:X}", (uint)&pCents);
pointerStruct->Dollars = 20;
*pCents = 50;
Console.WriteLine("amount1 contains " + amount1);
--pointerStruct;
Console.WriteLine("amount2 has address 0x{0:X} and contains {1}",
(uint)pointerStruct, *pointerStruct);
MyStruct* pTempCurrency = (MyStruct*)pCents;
pCents = (byte*)(--pTempCurrency);
Console.WriteLine("Address of pCents is now 0x{0:X}", (uint)&pCents);
Console.WriteLine("
Now with classes");
MyClass amount3 = new MyClass();
fixed (long* pDollars2 = &(amount3.Dollars))
fixed (byte* pCents2 = &(amount3.Cents)) {
Console.WriteLine("amount3.Dollars has address 0x{0:X}", (uint)pDollars2);
Console.WriteLine("amount3.Cents has address 0x{0:X}", (uint)pCents2);
*pDollars2 = -100;
Console.WriteLine("amount3 contains " + amount3);
}
}
}
struct MyStruct {
public long Dollars;
public byte Cents;
public override string ToString() {
return "$" + Dollars + "." + Cents;
}
}
class MyClass {
public long Dollars;
public byte Cents;
public override string ToString() {
return "$" + Dollars + "." + Cents;
}
}