1 van 1

[c#] pointers voor conversie van data

Geplaatst: zo 26 jul 2009, 20:59
door Vladimir Lenin
in C# kan je indien je de code binnen de unsafe {}-zone zet toch met pointers werken, stel ik heb een array van bytes, en ik benaders ze met een uint*-pointer kan ik dan gewoon per 4 bytes (32-bit dus; komt overeen met een uint) lezen, en hoe implementeer je dat in C#. Uiteraard weet ik hier dat het aantal bytes deelbaar is door 4. Ik wil dit gebruiken, omdat ik een klasse geschreven heb die uint-types als kleuren behandelt, en ze zo snel in en uit een afbeelding schrijven.

Re: [c#] pointers voor conversie van data

Geplaatst: zo 26 jul 2009, 22:38
door virtlink
Om unsafe code te kunnen gebruiken moet je (zoals je zei) je code in een unsafe block zetten, of een methode unsafe declareren, en verder de /unsafe optie inschakelen in Visual Studio (of met /unsafe compileren vanaf de command line).

Je kan een byte array (byte[]) via pointers benaderen d.m.v. het fixed keyword. Bijvoorbeeld:

Code: Selecteer alles

public static unsafe void Zero(byte[] array)

{

int count = array.Length;

fixed (byte* pArr = array)

{

while (count > 0)

{

*pArr = 0;	// *var = de waarde op de plaats waar de pointer naar wijst.

pArr++;	   // Zonder sterretje de waarde van de pointer, dus het adres.

count--;

}

}

}

public static unsafe void Zero(Point p)

{

fixed (int* x = &p.x, y = &p.y)	// &var is het adres van de waarde,

{

  // dus maakt er een pointer van.

*x = 0;

*y = 0;

}

}

Re: [c#] pointers voor conversie van data

Geplaatst: ma 27 jul 2009, 15:21
door Vladimir Lenin
idd maar mij vraag was eerder, stel je hebt een array van het type byte.

Code: Selecteer alles

byte[] invoer = new byte[512];
laat ons zeggen. Vervolgens vullen we die array met gegevens uit een bestand of een device, dat doet er eventjes niet veel toe. Kan ik dan een array van uint[] opvullen dus:

Code: Selecteer alles

uint[] uitvoer = new uint[128];
Zodat stel dat invoer er zo uitziet:

Code: Selecteer alles

invoer = {0x3e,0xc7,0x01,0x15,...}//hier eventjes pseudocode
dat ik dan bij uitvoer iets krijg van de vorm:

Code: Selecteer alles

uitvoer = {0x3ec70115,...}
Zonder zelf met shift-operaties en geheugenoproepen te moeten werken maar gewoon met een uint*-pointer toe te passen op de array van bytes.

Re: [c#] pointers voor conversie van data

Geplaatst: ma 27 jul 2009, 18:47
door virtlink
Je kan gewoon casten naar een ander pointer type, net als in C++. Merk op dat de fixed pointers niet te veranderen zijn, vandaar de pResult = pfResult assignment. Dus:

Code: Selecteer alles

static void Main(string[] args)

{

uint[] values;

values = GetUInts(new byte[]{

0x3e,0xc7,0x01,0x15,

0xBE,0xBA,0xFE,0xCA,

0x01,0x23,0x45,0x67});

foreach (uint val in values)

{

Console.WriteLine("{0:X}", val);

}

Console.ReadLine();

}

public static unsafe uint[] GetUInts(byte[] array)

{

int count = array.Length / 4;

uint[] result = new uint[count];

fixed (uint* pfResult = result)

{

uint* pResult = pfResult;

fixed (byte* pArr = array)

{

uint* pArr2 = (uint*)pArr;

while (count > 0)

{

*pResult = *pArr2;

pResult++;

pArr2++;

count--;

}

}

}

return result;

}
Deze code geeft het volgende resultaat, wat misschien gespiegeld is ten opzichte van je verwachtingen, maar dat komt omdat de systemen waar .Net op draait little-endian zijn:

Code: Selecteer alles

1501C73E

CAFEBABE

67452301