[c#] pointers voor conversie van data
- 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-- (Владимир Ильич Ульянов)
--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:
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..."
- Berichten: 829
Re: [c#] pointers voor conversie van data
idd maar mij vraag was eerder, stel je hebt een array van het type byte.
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:
Zodat stel dat invoer er zo uitziet:
dat ik dan bij uitvoer iets krijg van de vorm:
Zonder zelf met shift-operaties en geheugenoproepen te moeten werken maar gewoon met een uint*-pointer toe te passen op de array van bytes.
Code: Selecteer alles
byte[] invoer = new byte[512];
Code: Selecteer alles
uint[] uitvoer = new uint[128];
Code: Selecteer alles
invoer = {0x3e,0xc7,0x01,0x15,...}//hier eventjes pseudocode
Code: Selecteer alles
uitvoer = {0x3ec70115,...}
"Als je niet leeft zoals je denkt, zul je snel gaan denken zoals je leeft."
--Vladimir Lenin-- (Владимир Ильич Ульянов)
--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:
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
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;
}
Code: Selecteer alles
1501C73E
CAFEBABE
67452301
"Niet gehinderd door enige kennis van zaken..."