2 Stimmen

C++ Serialisierung von VC6 bis Visual Studio 2010 hoch

Ich versuche, eine Datei zu lesen/öffnen, die mit einem VC++6-Build in einem in Visual Studio 2013 erstellten C++-Programm serialisiert wurde, einige Attribute/Werte werden nicht gelesen oder sind auf irgendeine Weise verloren gegangen.

Bitte helfen Sie mir zu verstehen, was in den beiden Versionen anders ist und wie ich es möglicherweise lösen könnte.

Es wurde mit CArchive folgendermaßen gespeichert:

void CCubeShelf::Serialize(CArchive &ar,BOOL bChildren, int iVersion)
{
    if(ar.IsStoring())
    {
        m_dwProperties |= CSHELF_MERCH | CSHELF_MERCH_DEPTH;
        ar << m_dwProperties;
        ar << m_iShelfNum;
        ar << m_fDividerWidth;
        ar << m_fDividerSpacing;

        ar << m_fGrillHeight;
        ar << m_crGrillColor;
        ar << m_fMercHeight;
        ar << m_fMerchDepth;
        ar << m_csFrontPath;
        ar << m_csLeftPath;
        ar << m_csTopPath;
    }
    else
    {
        ar >> m_dwProperties;
        ar >> m_iShelfNum;
        ar >> m_fDividerWidth;
        ar >> m_fDividerSpacing;
        ar >> m_fGrillHeight;
        ar >> m_crGrillColor;
        if( m_dwProperties & CSHELF_MERCH ) ar >> m_fMercHeight;
        if( m_dwProperties & CSHELF_MERCH_DEPTH )
        {
            ar >> m_fMerchDepth;
            ar >> m_csFrontPath;
            ar >> m_csLeftPath;
            ar >> m_csTopPath;
        }
    }

    CCube::Serialize(ar,bChildren,iVersion);
}

1voto

Jabberwocky Punkte 44828

Ich hatte gerade ein ähnliches Problem. Es hatte mit dem bool Typ zu tun, der in VC6 nicht unterstützt wurde.

Ich hatte diese Klasse:

class CTest
{
  BOOL m_test ;
  ...
}

Während der Deserialisierung habe ich an einer Stelle Folgendes gemacht:

ar >> m_test ;
m_test = !m_test ;

Und während der Serialisierung habe ich Folgendes gemacht:

ar << !m_test ;  // das Problem war hier

Erinnerung: BOOL ist tatsächlich auf VC6 und VC2010 als int typedefiniert.

Da es in VC6 keinen echten bool Typ gibt, ist der Typ von !m_test tatsächlich int und daher wird ar << !m_test CArchive::operator<<(int) aufgerufen. Aber in VC2010 ist der Typ von !m_test bool und daher wird CArchive::operator<<(BYTE) aufgerufen und es gehen 3 Bytes in Ihrer Datei verloren. Beim nächsten Deserialisieren der Klasse wird alles, was nach m_test kommt, verschoben und wir lesen Müll und das Programm könnte sogar abstürzen.

Die Lösung bestand einfach darin, !m_test in int zu casten.

ar << (DWORD)!m_test ;

0voto

WPFKK Punkte 1249

Zu beachten ist: Im C++ ist ein bool ein Bit, das '0' oder '1' ist und als int abgelegt wird.

Also beim Lesen von carchive oder beim Verwenden eines Binary Readers in C# muss man int 32 lesen und entsprechend handeln.

Ich bin diesem Weg gefolgt:

var br = new BinaryReader(targetStream);
....
....
,....
var boolWert = br.ReadInt32() == 1;
....
....
....

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X