Forum: PC-Programmierung C++ zu C# Code konvertieren


von Farin (Gast)


Angehängte Dateien:

Lesenswert?

Hei Leute

Ich versuche gerade eine C++ Awendung auf .Net umzuschreiben. Leider 
habe ich ein Problem mit dieser CRC Kalkulierung. Da sie etwas speziell 
ist, benötige ich Sie genau so wie im C++-File. Ich habe das ganze 
umgeschrieben nur irgendwie funktioniert das Ding nicht!

Könnte mir vielleicht jemand sagen wo mein Fehler liegt. Ich seh' 
irgendwie den Wald vor lauter Bäumen nicht mehr..

Danke und Gruss

Farin

von Peter II (Gast)


Lesenswert?

>  StreamReader sr = new StreamReader(file);

http://msdn.microsoft.com/de-de/library/system.io.streamreader%28v=vs.80%29.aspx

Implementiert einen TextReader, der Zeichen aus einem Bytestream in 
einer bestimmten Codierung liest.

Das ist bestimmt nicht was du willst. Du solltest einen binary Reader 
verwenden.


http://msdn.microsoft.com/de-de/library/system.io.binaryreader.aspx

von Farin (Gast)


Angehängte Dateien:

Lesenswert?

Ok ich hab den StreamReader raus und den BinaryReader reingemacht.. 
Leider ist das Ergebnis noch immer nicht das Gleiche wie vom C++ File.

Kannst du mir vielleicht noch einmal helfen?

Danke und Gruss

Farin

von casud (Gast)


Lesenswert?

Wieso benutzt du in der C++-Version 'unsigned int' und in der C#-Version 
'UInt64'?

von Farin (Gast)


Lesenswert?

Stimmt! Mein Fehler!

Ich hab einen UInt32 draus gemacht. Erhalte aber noch immer das falsche 
Resultat...

von casud (Gast)


Lesenswert?

Noch ein Fehler du benutzt in der C++-Variante 'unsigned short fileData' 
und in der C#-Variante 'byte'.

Das muss deshalb eher so aussehen
1
for (i = 0; i < size / 2; i +=2 )
2
{
3
    uiFileCRC |= ((ushort)fileBuffer[i] | ((ushort)fileBuffer[i + 1] << 8));
4
...
5
}

von casud (Gast)


Lesenswert?

Achja die Division durch 2 fliegt dann natürlich raus.

von Farin (Gast)


Lesenswert?

Dies hat einen spezifischen Grund.. Ich weiss nicht was fread in der C++ 
Variante überhaupt ausliest. Er liest nach vorgabe unsigned char(8 bit) 
in ein unsigned short array(16 bit pro eintrag). Was macht der genau? 
Jeweils zwei chars pro short oder ein char pro short und dann shiften?

von Yalu X. (yalu) (Moderator)


Lesenswert?

Nach Zeile 32 im C#-Programm fehlt
1
  size++;

Es ist aber nicht korrekt, bei ungerader Blockgröße einfach 0xFF-Bytes
einzufügen (das ist im C++-Programm schon falsch):
1
  if (size & 0x01) {
2
    printf("Add one byte because odd file length\n\r");
3
    fileData[size] = 0xFF;
4
    size++;
5
  }

Das muss man vermutlich am Ende der Datei machen, aber ganz sicher nicht
in der Mitte, weil sonst das CRC-Ergebnis davon abhängt, wie die die
Datei beim Einlesen gestückelt wird.

Bei gewöhnlichen Dateien tritt der Fehler wahrscheinlich nicht in
Erscheinung, da die fread- bzw. Read-Funktion bei jedem Aufruf bis auf
den letzten die gewünschte Anzahl von Bytes (2048) lesen wird und 2048
eine gerade Zahl ist.

Ist die Datenquelle aber keine Datei, sondern bspw. eine serielle
Schnittstelle, wird die Funktion ziemlich sicher bei gleichen Daten
jedesmal ein anderes Ergebnis liefern.

Ich verstehe aber sowieso nicht, warum im Originalprogramm die Daten
16-bit-weise verarbeitet werden. Durch die Art und Weise, wie dies
gemacht wird, hängt das Ergebnis nämlich zusätzlich von der Endianess
der verwendeten Plattform ab.

Das Originalprogramm ist also ziemlicher Murks. Wenn du dazu kompatibel
bleiben musst, kannst du diesen Murks übernehmen. Wenn du aber eine
ordentliche CRC berechnen möchtest, solltest du dir eine andere Vorlage
suchen.

von Karl H. (kbuchegg)


Lesenswert?

Yalu X. schrieb:

> Das Originalprogramm ist also ziemlicher Murks. Wenn du dazu kompatibel
> bleiben musst, kannst du diesen Murks übernehmen. Wenn du aber eine
> ordentliche CRC berechnen möchtest, solltest du dir eine andere Vorlage
> suchen.

Ergänzend:
Es würde mich schon sehr wundern, wenn es in der umfangreichen .Net 
Bibliothek nicht schon eine fix&fertige CRC Berechnung gäbe.

von Farin (Gast)


Lesenswert?

Es gibt alles fixfertig. Aber das Problem ist. Dieser Algorythmus wurde 
auf einer integrierten Schaltung verwendet. Und um diese Schaltung noch 
verwenden zu können muss mein Tool diese spezielle CRC auch so berechnen 
können.

Ich weiss es ist nervig und ich würde jeden anderen Weg bevorzugen aber 
es geht nunmal einfach nicht anders...

von Farin (Gast)


Lesenswert?

Ok Leute ich habs! Das Problem war effektiv das ushort/byte array in das 
ich die Daten kopiert habe. Ich habe das Kopieren der Daten nun 
folgendermassen realisiert und schon gehts perfekt wie ichs wollte:
1
 if ((rdr.BaseStream.Length - rdr.BaseStream.Position) >= 2048)
2
 {
3
     Buffer.BlockCopy(rdr.ReadBytes(2048), 0,fileBuffer, 0, 2048);
4
     size = 2048;
5
 }
6
 else
7
 {
8
     int tempsize = (int)(rdr.BaseStream.Length - rdr.BaseStream.Position);
9
     Buffer.BlockCopy(rdr.ReadBytes(2048), 0, fileBuffer, 0, tempsize);
10
     size = tempsize;
11
 }

Danke an alle Helfer. Ihr seid super!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.