C++ to C#
-
Habe hier ein kleines C++ Proggramm das eine Checksumme berechnet:
unsigned char rawData[128] = { 0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3, 0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C, 0xAE, 0xE4, 0x23, 0x00, 0xAA, 0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19, 0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4, 0x79, 0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51, 0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35 }; unsigned int cs(unsigned int cs, unsigned int *p, unsigned int sz) { const unsigned int poly = 0xEDB88320; unsigned int tmp1, tmp2; while (sz--) { tmp1 = 0; tmp2 = cs & poly; for (int i = 0; i <= 31; i++) tmp1 ^= ((tmp2 >> i) & 1); cs = *p++ ^ ((cs << 1) | tmp1); } return cs; } int _tmain(int argc, _TCHAR* argv[]) { printf("CHECKSUM -> %04X\n", 0xFFFF & cs((unsigned short)*(&rawData[0]), (unsigned int *)(&rawData[4]),0x7c /4)); while (1); return 0; }
beim versuch es in C# nachzubauen bin ich aber gescheitert:
namespace cs_0424 { public partial class Form1 : Form { private byte[] rawData = { 0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3, 0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C, 0xAE, 0xE4, 0x23, 0x00, 0xAA, 0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19, 0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4, 0x79, 0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51, 0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35 }; public Form1() { InitializeComponent(); } private unsafe uint cs(uint cs, uint p, uint sz) { const uint poly = 0xEDB88320; uint tmp1; uint tmp2; while (sz-- != 0) { tmp1 = 0; tmp2 = cs & poly; for (int i = 0; i <= 31; i++) { tmp1 ^= ((tmp2 >> i) & 1); } cs = p++ ^ ((cs << 1) | tmp1); } return cs; } private void button1_Click(object sender, EventArgs e) { textBox1.Text = Convert.ToString(0xFFFF & cs(Convert.ToUInt32((ushort) rawData[0]), (uint)(rawData[4]), 0x7C / 4)); } } }
Es wird zwar eine Checksumme ausgegeben aber die falsche
Evtl. hat jemand einen Tip für mich!
Grüße
-
genome schrieb:
Evtl. hat jemand einen Tip für mich!
Ja. Und zwar würde ich Debuggen bzw. die Ergebnisse der Zwischenschritte ausgeben. Dann findest du bestimmt heraus, wo der Unterschied ist.
-
unsigned int *p
vs.
uint p
sowie
*p++
vs.
p++
Und der Aufruf in deinem C#-Code von der Methode cs ist auch falsch.
Weißt du überhaupt was Zeiger sind?
-
Das mit den Zeigern war mir mehr oder weniger klar habe ich auch schon vorher korrigiert!
namespace cs_0424 { public partial class Form1 : Form { private byte[] rawData = { 0x08, 0x00, 0xCB, 0x47, 0x45, 0x0E, 0x01, 0x00, 0x45, 0xE0, 0xCF, 0x2E, 0xD9, 0xEF, 0x72, 0xE3, 0x08, 0x95, 0xF4, 0xF6, 0xF8, 0x0F, 0x70, 0x49, 0x8B, 0xBF, 0x7C, 0xAE, 0xE4, 0x23, 0x00, 0xAA, 0x57, 0x56, 0x31, 0x5A, 0x5A, 0x5A, 0x32, 0x48, 0x5A, 0x42, 0x38, 0x30, 0x33, 0x35, 0x34, 0x31, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x19, 0x80, 0x0C, 0x08, 0x00, 0x00, 0x00, 0xFB, 0xB6, 0xFF, 0x92, 0x3C, 0x5E, 0xF3, 0x77, 0xC8, 0xB4, 0x79, 0x96, 0xA4, 0x72, 0xE2, 0x0C, 0x09, 0xFC, 0x4C, 0x51, 0x6C, 0x4D, 0xDC, 0x27, 0xFC, 0x51, 0x8C, 0x49, 0x7A, 0xCB, 0xF2, 0xD9, 0x5C, 0xF8, 0xDA, 0xD4, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x92, 0x30, 0x6C, 0x35 }; public Form1() { InitializeComponent(); } private unsafe uint cks(uint cs, uint* p, uint sz) { const uint poly = 0xEDB88320; uint tmp1; uint tmp2; while (sz-- != 0) { tmp1 = 0; tmp2 = cs & poly; for (int i = 0; i <= 31; i++) { tmp1 ^= ((tmp2 >> i) & 1); } cs = *p++ ^ ((cs << 1) | tmp1); } return cs; } private unsafe void button1_Click(object sender, EventArgs e) { textBox1.Text = Convert.ToString(cks((ushort)rawData[0], (uint*)(rawData[4]), 0x7C / 4)); } } }
Der Hund liegt denke ich in dieser Zeile begraben:
cs = *p++ ^ ((cs << 1) | tmp1);
-
Nee, sondern
(uint*)(&rawData[4]) // Adress-Operator (&) ist wichtig!
-
Ah genau danke!
Aber dan bekomme ich folgenden Fehler:
"Sie können nur die Adresse eines unfixed-Ausdrucks innerhalb eines fixed-Anweisungsinitialisierers abrufen."Wieso ist es hier nicht möglich den Zeiger auf das Element zu übergeben?
Grüße
-
Erkunde dich mal nach den C#-Schlüsselwörtern unsafe und fixed.
Aber anstatt den C++-Code 1:1 mittels Zeiger nachzubauen, wäre es wohl besser, einfach das Array zu übergeben und mittels eines Index darauf zuzugreifen:
private uint cks(uint cs, byte[] rawData, uint sz) { const uint poly = 0xEDB88320; uint tmp1; uint tmp2; int i = 4; // edit: nicht 0, sondern soll ja bei 4 beginnen while (sz-- != 0) { tmp1 = 0; tmp2 = cs & poly; for (int i = 0; i <= 31; i++) { tmp1 ^= ((tmp2 >> i) & 1); } cs = rawData[i] ^ ((cs << 1) | tmp1); i++; } return cs; }
Da der Original C++-Code jedoch immer int-weise die Checksumme berechnet, müßtest du dies noch einarbeiten, d.h. innerhalb der Schleife jeweils 4 Byte aus dem Array lesen und zu einem int zusammenfügen, z.B. mittels BitConverter.
-
Th69 schrieb:
int i = 4; // edit: nicht 0, sondern soll ja bei 4 beginnen
Wäre vielleicht fesch wenn man das der Funktion als Parameter mitgeben könnte
-
Wie, sowas geht?