How to serialize a CString using boost
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 seri开发者_JS百科alize 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?
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).
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);
}
精彩评论