ByteArray - Dynamisch, Referenz

26/07/2009 - 17:14 von Martin Greul | Report spam
Hallo,

weiß jemand wie man ein dynamisches Array korrekt macht, wenn man die
Lànge nicht kennt? Basic gibt es das Redim, oder?

Referenzübergabe, ist das so richtig?
Byte[] bytesSend = new Byte[1000];
Endian.Test_Send_ByteArrayAsReference(ref bytesSend);


Hier tue ich Bitweise verschieben, das ist klar.
bytesSend[0] = (Byte)(i >> 24);
bytesSend[1] = (Byte)(i >> 16);
bytesSend[2] = (Byte)(i >> 8);
bytesSend[3] = (Byte)i;


Das habe ich aus dem Netz, so ganz ist mir da snicht klar.
Warum wird hier mit FF & gemacht?

uint v2 = (uint)v;
return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));

Danke für Tipps.

Grüße Martin

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WA_ByteArray_01
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
Endian.Test_Send();
Endian.Test_Receive();

Byte[] bytesSend = new Byte[1000];

Endian.Test_Send_ByteArrayAsReference(ref bytesSend);

}
}
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO;

namespace WA_ByteArray_01
{
class Endian
{
public static short Swap(short v)
{
return (short)(((v >> 8) & 0x00FF) | ((v << 8) & 0xFF00));
}


public static int Swap(int v)
{
// only test

uint v2 = (uint)v;
return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));
}

public static void Test_Send()
{
Byte[] bytesSend = new Byte[1000];

int i = 365;
// write in big-endian order, regardless of host order
bytesSend[0] = (Byte)(i >> 24);
bytesSend[1] = (Byte)(i >> 16);
bytesSend[2] = (Byte)(i >> 8);
bytesSend[3] = (Byte)i;

}

public static void Test_Receive()
{
Byte[] bytesReceive = new Byte[1000];

bytesReceive[0] = 0;
bytesReceive[1] = 0;
bytesReceive[2] = 1;
bytesReceive[3] = 109;

int i = 0;
Byte b1 = bytesReceive[0];
Byte b2 = bytesReceive[1];
Byte b3 = bytesReceive[2];
Byte b4 = bytesReceive[3];

// How I get now the length?
}

public static void Test_Send_ByteArrayAsReference(ref Byte[]
bytesSend)
{

int i = 365;
// write in big-endian order, regardless of host order
bytesSend[0] = (Byte)(i >> 24);
bytesSend[1] = (Byte)(i >> 16);
bytesSend[2] = (Byte)(i >> 8);
bytesSend[3] = (Byte)i;

}

}
}
 

Lesen sie die antworten

#1 Elmar Boye
26/07/2009 - 19:24 | Warnen spam
Martin Greul schrieb:
weiß jemand wie man ein dynamisches Array korrekt macht, wenn man die
Lànge nicht kennt? Basic gibt es das Redim, oder?



Es gibt keine dynamischen .NET Arrays.
Visual Basics Redim erstellt eine Kopie und kopiert die Daten in das Neue,
siehe Array.Copy

Referenzübergabe, ist das so richtig?



Schon.

Byte[] bytesSend = new Byte[1000];
Endian.Test_Send_ByteArrayAsReference(ref bytesSend);



Anstatt ref kannst Du jeweils das (neue oder alte Array) zurückgeben lassen.


byte[] input = new byte[] { 0x12, 0x34, 0x56, 0x78, 0xAA, 0xBB, 0xCC, 0xEE };
byte[] output = SwapUInt32Array(input);

private byte[] SwapUInt32Array(byte[] input)
{
// Keine Konvertierung notwendig
if (!BitConverter.IsLittleEndian)
return input;

byte[] output = new byte[input.Length];
for (int index = 0; index < input.Length; index += 4)
{
output[index] = input[index + 3];
output[index + 1] = input[index + 2];
output[index + 2] = input[index + 1];
output[index + 3] = input[index];
}
return output;
}

Da fehlen einige Prüfungen (null, Length % 4).
Und via unsafe Code dürfte es ein bisschen schneller laufen ;-)

Und es wàre eine weitere Überladung für einzelne Integer denkbar,
die sie direkt in ein Byte-Array umwandelt:

byte[] o2 = SwapUInt32(v2);

private byte[] SwapUInt32(uint input)
{
byte[] output = new byte[4];

if (BitConverter.IsLittleEndian)
{
for (int index = 0; index < output.Length; index++)
{
output[index] = (byte)(input & 0xff);
input = input >> 8;
}
}
else
{
for (int index = output.Length - 1; index >= 0; index--)
{
output[index] = (byte)(input & 0xff);
input = input >> 8;
}
}
return output;
}

Hier tue ich Bitweise verschieben, das ist klar.
bytesSend[0] = (Byte)(i >> 24);
bytesSend[1] = (Byte)(i >> 16);
bytesSend[2] = (Byte)(i >> 8);
bytesSend[3] = (Byte)i;



da verschiebst Du im Prinzip eher "byteweise",
das heißt Du schneidest den (unsigned) integer durch den Cast ab.

Das habe ich aus dem Netz, so ganz ist mir da snicht klar.
Warum wird hier mit FF & gemacht?

uint v2 = (uint)v;
return (int)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000));



Da die Verschiebeoperation auf einem unsigned integer erfolgt
bleibt mehr als 1 Byte übrig, was noch entfernt werden muß.
Ich persönlich würde erst undieren und danach verschieben,
wie in der letzten Variante. Aber sieh den Unterscheid selbst:

uint v2 = 0x12345678;
Console.WriteLine("{0:x4} => {1:x4} => {2:x4} => {3:x4}",
v2,

(uint)(((v2 >> 24)) |
((v2 >> 8)) |
((v2 << 8)) |
((v2 << 24))),

(uint)(((v2 >> 24) & 0x000000FF) |
((v2 >> 8) & 0x0000FF00) |
((v2 << 8) & 0x00FF0000) |
((v2 << 24) & 0xFF000000)),

(uint)(((v2 & 0x000000FF) << 24) |
((v2 & 0x0000FF00) << 8) |
((v2 & 0x00FF0000) >> 8) |
((v2 & 0xFF000000) >> 24))
);

Tipp: Wenn Du in VS2008 den Cursor über Teilausdrücke positionierst,
siehst Du die Zwischenergebnisse - z. B. (v2 << 8) = 0x34567800

Weitere Lösungen findest Du unter:
<URL:http://stackoverflow.com/questions/...endian>
die zu nutzen ist vermutlich besser, wenn Du dabei unsicher bist.

Gruß Elmar

Ähnliche fragen