【问题标题】:C++ serialization from VC6 to Visual Studio 2010 up从 VC6 到 Visual Studio 2010 的 C++ 序列化
【发布时间】:2014-02-14 11:05:57
【问题描述】:

我正在尝试读取/打开已在 Visual Studio 2013 中创建的 C++ 程序中使用 VC++6 构建序列化的文件,某些属性/值未被读取或以某种方式丢失。

请帮助我了解这两个版本有什么不同以及如何解决它。

使用 CArchive 存储如下:

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);
}

【问题讨论】:

  • 这完全取决于如何数据被序列化。你必须告诉我们更多关于这方面的信息。
  • 也许你在代码的其他地方序列化了 CTime 对象。在 VS6 中 CTime 只有 4 个字节,但从 VS2003 到 CTime 是 8 个字节长,所以如果你用 VS2013 反序列化一个之前用 VS6 序列化过的 CTime 对象,你会遇到麻烦。
  • 不,很遗憾不是问题所在。我可以检查任何其他课程吗?
  • 事实证明,序列化从来都不是问题,但实际上 = 运算符在升级到 Visual Studio 后不再重载,有什么想法吗?
  • 你是指哪个= operator

标签: visual-c++ serialization mfc visual-c++-6


【解决方案1】:

我现在也遇到了类似的问题。它与 VC6 不支持的 bool 类型有关。

我有这门课:

class CTest
{
  BOOL m_test ;
  ...
}

在反序列化过程中,我在某个时候这样做了:

ar >> m_test ;
m_test = !m_test ;

在序列化过程中我这样做了:

ar << !m_test ;  // problem was here

提醒:BOOL 实际上在 VC6 和 VC2010 上的 typedefd 为 int

由于 VC6 没有真正的 bool 类型,!m_test 的类型实际上是 int,因此 ar &lt;&lt; !m_test 调用 CArchive::operator&lt;&lt;(int)。 但是在 VC2010 上,!m_test 的类型是bool,因此CArchive::operator&lt;&lt;(BYTE) 被调用,你在文件中丢失了 3 个字节。然后下次反序列化该类时,m_test 之后的所有内容都会被转移,我们会读取垃圾,程序甚至可能崩溃。

解决方案只是将!m_test转换为int

ar << (DWORD)!m_test ;

【讨论】:

    【解决方案2】:

    需要注意的是:C++ bool 是 '0' 或 '1' 位,归档为 int。

    因此,当从存档读取或在 C# 中使用二进制读取器时,您必须读取 int 32 并进行相应操作。

    我是这样走的:

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

    【讨论】:

    • 虽然此代码可能会回答问题,但提供有关此代码为何和/或如何回答问题的额外上下文可提高其长期价值。
    猜你喜欢
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2018-03-02
    • 2014-11-24
    相关资源
    最近更新 更多