2011-01-26 2 views
1

Я пытаюсь использовать boost :: serialization для замены одной части существующего проекта, который реализует свои собственные методы для сериализации, но не так хорош. Однако я столкнулся с некоторыми проблемами, потому что приложение использует MFC. Я пытался сериализации CString следующимКак сериализовать CString с помощью boost

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 \ подталкивание \ сериализации \ access.hpp (118): ошибка C2039: 'Serialize': есть не член 'АТЛ :: CStringT'

в access.hpp он говорит

// 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!!! 

Поэтому я предполагаю, что CString имеет сериализацию из-за MFC.

Теперь мне интересно, что мне делать? Есть ли обходной путь? Я пытаюсь избежать переопределения CStrings в std: string, потому что их так много, что он подразумевает повторение всего проекта.

Кроме того, я хочу сериализовать CArray, но я получаю тот же тип ошибки, что serialize не является членом CArray.

EDIT: Проблема 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); 
} 

, но это не вызывает сериализацию класса. Есть ли прямой способ сериализации массивов, таких как std :: vector или std :: list в примерах Boost?

ответ

2

Вы можете использовать только save и load, если вы работаете в этом классе, можете добавить BOOST_SERIALIZATION_SPLIT_MEMBER() в определение. Так как вы не можете сделать это для строки, вам нужно реализовать Повысьте сериализации с точки зрения метода serialize:

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

Это менее эффективно, но он должен по крайней мере, компилировать.

EDIT: На самом деле, вы можете разделить свободную функцию, но вам нужно добавить это вместе с вашими сохранения и загрузки функций:

#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); 
} 
+0

Обратите также внимание на то, что в зависимости от версии вашего компилятора вам может потребоваться поместить все три слова «serialize», 'save' и' load' в пространство имен 'boost :: serialization'. (Обогреть их с помощью 'namespace boost {namespace serialization {...}}'.) –

4

Вы должны использовать BOOST_SERIALIZATION_SPLIT_FREE (T), где T является именем типа (например, CString или CArray), чтобы генерировать код, который будет разделять сериализацию на нагрузку и сохранять, не навязчиво. Это эквивалентно BOOST_SERIALIZATION_SPLIT_MEMBER для класса (т. Е. Навязчивого).

Смежные вопросы