[c#] pointers voor conversie van data

Moderators: jkien, Xilvo

Reageer
Gebruikersavatar
Berichten: 829

[c#] pointers voor conversie van data

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.
"Als je niet leeft zoals je denkt, zul je snel gaan denken zoals je leeft."

--Vladimir Lenin-- (Владимир Ильич Ульянов)

Berichten: 158

Re: [c#] pointers voor conversie van data

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;

}

}
"Niet gehinderd door enige kennis van zaken..."

Gebruikersavatar
Berichten: 829

Re: [c#] pointers voor conversie van data

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.
"Als je niet leeft zoals je denkt, zul je snel gaan denken zoals je leeft."

--Vladimir Lenin-- (Владимир Ильич Ульянов)

Berichten: 158

Re: [c#] pointers voor conversie van data

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
"Niet gehinderd door enige kennis van zaken..."

Reageer