.NET hat Probleme mit MFC



  • Hallo zusammen, wahrscheinlich habe ich das Problem. Ich versuche mit CStdioFile WriteString einen String in eine Datei zu schreiben mit MFC, und den dann mit BinaryReader ReadString .NET zu lesen. Es kommt immer die Fehlermeldung das versucht wird, über die Dateigrenzen hinaus zu lesen. WriteString schreibt "nach" dem String kein 0-Byte. Auch wenn ich es explizit hinzufüge, kommt die Fehlermeldung ...



  • Schreibst und liest du denn mit dem gleichen Encoding (und welches verwendest du)?



  • Bei MFC ist Unicode voreingestellt. Die Datei enthält kein Unicode. Hier der Code:

    void CSchreibeFürCsharpView::OnRButtonDown(UINT nFlags, CPoint point)
    {
    	// TODO: Fügen Sie hier Ihren Meldungsbehandlungscode ein, und/oder benutzen Sie den Standard.
    	//MessageBox(L"Meldung", 0, 0);
    	CStdioFile fi;
    	fi.Open(L"C:\\Projekte\\Test\\TestDatei", CFile::modeCreate | CFile::modeWrite);
    	int i1 = 2000;
    	int i2 = 4000;
    	CString str = _T("Text1")  _T("Text2\n"); // oder: _T("Text1")  _T("Text2");
    	byte by = 0;
    	fi.Write(&i1, 4);
    	fi.WriteString(str); 
    	fi.Write(&by, 1);
    	fi.Write(&by, 1);  // einmal geht auch nicht
    	fi.Write(&i2, 4);
    	fi.Close();
    	MessageBox(L"Fertig", 0, 0);
    	CView::OnRButtonDown(nFlags, point);
    }
    
    private void button1_Click(object sender, EventArgs e)
            {
                FileStream fs = new FileStream("C:\\Projekte\\Test\\TestDatei", FileMode.Open);
                BinaryReader br = new BinaryReader(fs, Encoding.Unicode); //  Habe verschiedene Encodigs ausprobiert
                MessageBox.Show(br.ReadInt32().ToString());
                MessageBox.Show(br.ReadString()); // Hier kommt die Fehlermeldung
                MessageBox.Show(br.ReadInt32().ToString());
                br.Close();
                fs.Close();
            }
    


  • BinaryReader ReadString erwartet das die länge des strings mit im datenstrom enthalten ist und zwar als prefix:

    https://docs.microsoft.com/en-us/dotnet/api/system.io.binaryreader.readstring?redirectedfrom=MSDN&view=net-5.0#System_IO_BinaryReader_ReadString

    Reads a string from the current stream. The string is prefixed with the length, encoded as an integer seven bits at a time.

    Wie sonst soll der reader wissen wie lange ein string in einem binary datenstrom ist?



  • Am besten du erzeugst mal in C# mit BinaryWriter eine zum C++ Code passende Datei und vergleichst dann mit einem HexViewer die beiden erzeugten Dateien.

    Schau auch mal in How BinaryWriter.Write() write string, um das interne Format zu verstehen.

    Wenn jedoch deine mit C++ erzeugte Datei die Vorgabe sein soll, dann mußt du auf ReadString() verzichten und selber den String (zeichenweise) parsen.

    PS: In deinem C++ Code solltest du für Write statt der Konstanten sizeof(T) verwenden.



  • Das mit dem prefix von einem Byte Länge hat geklappt. Was ist, wenn die Länge des Srings gross ist ? > 1000 ? Normalerweise sind Strings mit 0 abgeschlossen.



  • Oh Mann, probier das doch einfach aus. In der MS-Doku steht doch deutlich, dass der Längepräfix als int geschrieben wird, und zwar mit jeweils sieben Bit. Möglicherweise bedeutet das, dass wenn das höchste Bit gesetzt wird ein weiteres Präfixbyte erwartet wird. Das heißt, dass bereits ab einer Länge von 127 Zeichen ein zweites Präfixbyte erwartet wird. Also schreib doch einfach mal 128 Zeichen und guck dir im Hexeditor an, wie der Präfix aussieht.

    Edit:
    Und wenn du dir den Link angeschaut hättest, den TH69 gepostet hat, dann wüsstest du jetzt auch, dass der Präfix LEB128 kodiert ist.



  • Ja Ok, stimmt ! Dann wärs das. Danke Euch !!!


Anmelden zum Antworten