質問

I am trying to read/open a file that has been serialized with a VC++6 build in a C++ program created in Visual Studio 2013, some attributes/values are not being read or have gone missing somehow.

Please help me understand what is different in the two versions and how I could possible solve it.

It was stored using CArchive as follows:

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);
}
役に立ちましたか?

解決

I've just had a similar problem right now. It has to do with the bool type which was not supported on VC6.

I had this class:

class CTest
{
  BOOL m_test ;
  ...
}

During deserialisation I did this at some point :

ar >> m_test ;
m_test = !m_test ;

And during serialisation I did this:

ar << !m_test ;  // problem was here

Reminder: BOOL is actually typedefd as int on VC6 and on VC2010

As there is no true bool type with VC6, the type of !m_test is actually int and therefore ar << !m_test calls CArchive::operator<<(int). But on VC2010 the type of !m_test is bool and therefore CArchive::operator<<(BYTE) gets called and you loose 3 bytes in your file. Then next time you deserialize the class, everything that comes after m_test is shifted and we read garbage and the program could even crash.

The solution was simply to cast !m_testto int.

ar << (DWORD)!m_test ;

他のヒント

Thing to note is: C++ bool is a bit which is '0' or '1' and archived as int.

So when reading from carchive or using binary reader in C# you must read int 32 and do accordingly.

I followed this way:

var br= new BinaryReader(targetStream);
....
....
,....
var boolValue= br.ReadInt32()==1;
....
....
....
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top