如何使用 boost 序列化 CString

发布于 2024-10-14 10:51:37 字数 1823 浏览 6 评论 0原文

我正在尝试使用 boost::serialization 来替换现有项目的一部分,该项目实现了自己的序列化方法,但效果并不好。 但是,由于应用程序使用 MFC,我面临一些问题。我尝试按如下方式序列化 CString

template<class Archive>
void save(Archive & ar, CString & s, const unsigned int version) {  
  using boost::serialization::make_nvp;
  const std::basic_string<TCHAR> ss((LPCTSTR)s);
  ar & make_nvp("String", ss);
}
template<class Archive>
void load(Archive & ar, CString & s, const unsigned int version) {  
  using boost::serialization::make_nvp;
  std::string ss;
  ar & make_nvp("String",ss);
  s = ss.c_str;
}

但出现一些错误

boost_1_45_0\boost\序列化\access.hpp(118): 错误 C2039:“序列化”:不是 的成员 'ATL::CStringT'

在 access.hpp 中说

// 注意:如果您在此处遇到编译时错误
// 消息类似:
// 无法从 <文件类型 1> 转换参数 1 <文件类型2>
// 一个可能的原因是类 T 包含 
// 序列化函数 - 但序列化函数不是 
// 模板并对应于不同的文件类型
// 类存档。要解决此问题,请不要包含
// 序列化以外的存档类型
// 函数已定义!!!

所以我想象CString由于MFC而有一些序列化。

现在我想知道,我能做什么?有什么解决方法吗? 我试图避免将 CString 重新定义为 std:string,因为它们太多了,这意味着需要重新完成整个项目。

另外,我想序列化 CArray,但遇到相同类型的错误,即序列化不是 CArray 的成员。

编辑: 通过添加解决了 CString 问题

template<class Archive>
inline void serialize(Archive & ar, CString & s, const unsigned int file_version) {
    split_free(ar, s, file_version); 
}

我不知道为什么宏不起作用。然而,我仍然面临着 CArray 的问题。我尝试了一个简单的解决方案

ar & make_nvp("CArray",myCArray); 

,但它不会创建任何 XML。然后我尝试像这样迭代数组

for(int i=0; i < myCArray.GetCount(); i++) {
  MyClass* m = (MyClass*) myCArray.GetAt(i);      
  ar & BOOST_SERIALIZATION_NVP(m);
}

,但这并没有调用类的序列化。是否有任何直接的方法可以序列化 Boost 示例中的 std::vector 或 std::list 等数组?

I'm trying to use boost::serialization to replace one part of an existing project that implements its own methods for serialization but are not that good.
However, I'm facing some problems because the application uses MFC. I tried to serialize the CString as follows

template<class Archive>
void save(Archive & ar, CString & s, const unsigned int version) {  
  using boost::serialization::make_nvp;
  const std::basic_string<TCHAR> ss((LPCTSTR)s);
  ar & make_nvp("String", ss);
}
template<class Archive>
void load(Archive & ar, CString & s, const unsigned int version) {  
  using boost::serialization::make_nvp;
  std::string ss;
  ar & make_nvp("String",ss);
  s = ss.c_str;
}

But I'm getting some errors

boost_1_45_0\boost\serialization\access.hpp(118):
error C2039: 'serialize' : is not a
member of
'ATL::CStringT'

In access.hpp it says

// note: if you get a compile time error here with a
// message something like:
// cannot convert parameter 1 from <file type 1> to <file type 2 &>
// a likely possible cause is that the class T contains a 
// serialize function - but that serialize function isn't 
// a template and corresponds to a file type different than
// the class Archive.  To resolve this, don't include an
// archive type other than that for which the serialization
// function is defined!!!

So I imagine that the CString has some serialization due to MFC.

Now I'm wondering, what can I do? Is there any workaround?
I'm trying to avoid the redefinition of the CStrings to std:string because there are so many of them, that it implies to re do the entire project.

Also, I want to serialize a CArray but I'm getting the same type of error, that serialize is not a member of CArray.

EDIT:
The CString problem is fixed by adding

template<class Archive>
inline void serialize(Archive & ar, CString & s, const unsigned int file_version) {
    split_free(ar, s, file_version); 
}

I don't know why the macro doesn't work. However, I'm still facing problems with the CArray. I tried a simple solution

ar & make_nvp("CArray",myCArray); 

but that doesn't create any XML. And then I tried to iterate over the array like this

for(int i=0; i < myCArray.GetCount(); i++) {
  MyClass* m = (MyClass*) myCArray.GetAt(i);      
  ar & BOOST_SERIALIZATION_NVP(m);
}

but that isn't calling the serialization of the class. Is there any straight forward way to serialize arrays like the std::vector or std::list in the Boost examples?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你在我安 2024-10-21 10:51:37

您需要使用 BOOST_SERIALIZATION_SPLIT_FREE(T),其中 T 是类型名称(如 CString 或 CArray),以便生成以非侵入方式将序列化拆分为加载和保存的代码。这相当于类内的 BOOST_SERIALIZATION_SPLIT_MEMBER(即侵入式)。

You need to use BOOST_SERIALIZATION_SPLIT_FREE(T) where T is the type name (like CString or CArray) in order to generate the code that will split the serialization into load and save, non-intrusively. This is the equivalent of the BOOST_SERIALIZATION_SPLIT_MEMBER for within a class (i.e. intrusive).

终遇你 2024-10-21 10:51:37

如果您使用的类可以将 BOOST_SERIALIZATION_SPLIT_MEMBER() 添加到其定义中,则只能使用 saveload。由于您无法对字符串执行此操作,因此您需要根据 serialize 方法实现 Boost 序列化:

template<class Archive>
void serialize(Archive & ar, CString & s, const unsigned int version)
{
    std::string ss(s);
    ar & ss;
    s = ss.c_str;
}

这效率较低,但至少应该可以编译。

编辑:实际上,您可以拆分一个免费函数,但您需要将其与保存和加载函数一起添加:

#include <boost/serialization/split_free.hpp>

template<class Archive>
inline void serialize(Archive & ar, CString & s, const unsigned int file_version) {
    split_free(ar, s, file_version); 
}

You can only use save and load if you are working with a class you can add BOOST_SERIALIZATION_SPLIT_MEMBER() to the definition of. Since you can't do that for string, you need to implement Boost serialization in terms of a serialize method:

template<class Archive>
void serialize(Archive & ar, CString & s, const unsigned int version)
{
    std::string ss(s);
    ar & ss;
    s = ss.c_str;
}

This is less efficient, but it should at least compile.

EDIT: Actually, you can split a free function, but you need to add this along with your save and load functions:

#include <boost/serialization/split_free.hpp>

template<class Archive>
inline void serialize(Archive & ar, CString & s, const unsigned int file_version) {
    split_free(ar, s, file_version); 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文