32位MFC序列化CStringArray后64位反序列化报CArchiveException求助
MFC跨32/64位序列化CStringArray问题解决及注意事项
一、CStringArray跨平台序列化的可行方案
既然默认MFC序列化在跨32/64位时出了问题,可以绕过默认实现,自己写序列化逻辑来规避平台差异:
- 自定义序列化函数:在包含CStringArray成员的类的
Serialize方法中,不要直接调用m_stringArray.Serialize(ar),手动处理数组的长度和每个元素:void CYourClass::Serialize(CArchive& ar) { if (ar.IsStoring()) { // 用固定32位整数存储数组长度,避免INT_PTR的平台差异 UINT32 nCount = static_cast<UINT32>(m_stringArray.GetSize()); ar << nCount; // 逐个序列化CString元素 for (INT_PTR i = 0; i < m_stringArray.GetSize(); ++i) { ar << m_stringArray[i]; } } else { UINT32 nCount = 0; ar >> nCount; m_stringArray.SetSize(nCount); // 逐个反序列化CString元素 for (UINT32 i = 0; i < nCount; ++i) { ar >> m_stringArray[i]; } } } - 统一字符编码:确保32位和64位项目都使用Unicode编码编译(项目属性中设置
字符集为使用 Unicode 字符集),避免ANSI和Unicode序列化后的字节差异。
二、排查当前EOF异常的关键点
既然评论确认CStringArray本身跨平台序列化没问题,那问题大概率出在其他地方:
- 检查类中其他成员变量:有没有直接序列化
INT_PTR、UINT_PTR、指针这类长度随平台变化的类型?比如如果你的类里存了某个对象的指针,32位下是4字节,64位下是8字节,序列化后会导致后续数据偏移,触发EOF异常。 - 验证序列化版本号:确保32位和64位端的
DECLARE_SERIAL宏中指定的版本号一致,版本号不匹配会导致反序列化时直接出错。 - 检查字节对齐设置:两个平台的项目结构体/类字节对齐要保持一致(比如都设为8字节对齐),对齐方式不同会导致序列化后的内存布局错位,进而引发读取错误。
三、跨32/64位需重点检查的MFC数据类型
- 指针及指针相关类型:
LPVOID、LPCSTR、LPWSTR等,绝对不能直接序列化指针值,32位和64位下长度差一倍,会直接破坏数据结构。 - 平台相关整数类型:
INT_PTR、UINT_PTR、DWORD_PTR、LONG_PTR这些类型的长度随平台变化,序列化时必须转成固定大小的类型(比如UINT32或INT64)。 - MFC容器类:
CArray、CList、CMap这类容器的默认序列化会用INT_PTR存储元素数量,建议像CStringArray一样自定义序列化逻辑,改用固定长度类型存计数。 - 几何类扩展:
CRect、CPoint、CSize本身内部是LONG类型(32位),跨平台没问题,但如果自定义扩展了这些类添加了64位成员,必须注意序列化逻辑的兼容性。
内容的提问来源于stack exchange,提问作者GiordiX
相关产品推荐
相关产品推荐

