问题描述
||
我正在使用boost :: serialize序列化其中使用f.i.的文档一个juce :: String。像这样:
template<class Archive>
void serialize( Archive & ar,const unsigned int version )
{
ar & boost::serialization::make_nvp(\"title\",m_docTitle);
...
}
为了让boost :: serialize接受juce :: String作为我做的原始类型:
#include <boost/serialization/string.hpp>
template<class IStream>
inline IStream& operator >> (IStream& stream,juce::String& s)
{
std::wstring t;
stream >> t;
s = juce::String(t.c_str());
return stream;
}
BOOST_CLASS_IMPLEMENTATION(juce::String,boost::serialization::primitive_type)
可以很好地编译。序列化工作正常,我在XML中获得了条目:
<title>DocumentTitle</title>
应该是。但是,在反序列化时,我可以在>>运算符中跟踪返回的字符串为:
\"DocumentTitle</title>\"
也就是说,某些XML已被“修改”,这当然会在以后导致“输入流错误”异常。
最奇怪的部分是我直到一周前才完成这项工作... :(我不知道是什么使它现在无法正常工作...
编辑:一个显示示例的小示例代码再现了该行为,只有依赖关系得到了增强:
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>
#include <boost/archive/xml_woarchive.hpp>
#include <boost/archive/xml_wiarchive.hpp>
#include <sstream>
class JuceString
{
public:
JuceString(const std::wstring& str = L\"\") : m_str(str) {;}
JuceString(const JuceString& other) : m_str(other.m_str) {;}
JuceString& operator = (const JuceString& other)
{
if (this != &other)
{
m_str = other.m_str;
}
return *this;
}
const wchar_t* toWideCharPointer() const {
return m_str.c_str();
}
private:
std::wstring m_str;
};
template <class OStream>
OStream& operator<< (OStream& stream,const JuceString& stringToWrite)
{
return stream << stringToWrite.toWideCharPointer();
}
template <class IStream>
IStream& operator>> (IStream& stream,JuceString& s)
{
std::wstring t;
stream >> t;
s = JuceString(t.c_str());
return stream;
}
BOOST_CLASS_IMPLEMENTATION(JuceString,boost::serialization::primitive_type)
class Doc
{
friend class boost::serialization::access;
template<class Archive>
void serialize( Archive & ar,const unsigned int version )
{
ar & boost::serialization::make_nvp(\"title\",m_title);
}
public:
Doc() {;}
Doc(const std::wstring& s) : m_title(s) {;}
private:
JuceString m_title;
};
int main (int argc,char* argv[])
{
std::wstringstream stream;
{
// Serializing document
Doc doc(L\"DocumentTitle\");
boost::archive::xml_woarchive oa(stream);
oa << boost::serialization::make_nvp(\"Document\",doc);
}
{
// Deserializing document
Doc doc;
try
{
boost::archive::xml_wiarchive ia(stream);
ia >> boost::serialization::make_nvp(\"Document\",doc);
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
return 0;
}
而是使用文本存档在两种情况下都可以正常工作...
解决方法
最终,通过使用boost basic_xml_grammar解析operator >>中的字符串,我使它可以工作(对于XML存档nota bene),如下所示:
typedef boost::archive::basic_xml_grammar<wchar_t> xml_wgrammar;
template <class IStream>
IStream& operator>> (IStream& stream,JuceString& s)
{
std::wstring t;
xml_wgrammar grammar;
if (!grammar.parse_string(stream,t))
{
boost::serialization::throw_exception(
boost::archive::xml_archive_exception(boost::archive::xml_archive_exception::xml_archive_parsing_error)
);
}
s = JuceString(t.c_str());
return stream;
}
这将确保正确解析该字符串。
,问题出在你的ѭ6
当您这样做时:
std::wstring t;
stream >> t;
您读到下一个空格。在XML中,它位于结束标记之后,因此您正在读取boost希望能够在其中读取的部分流。
解决方案是要么在输出中强加一个空格,要么修改operator >>
以拒绝读取\'<\'之类的内容。我的猜测是,以前您要保存和恢复的字符串中有多余的空间。
假设您可以从std::wstring
进行设置/分配,并获得可用于创建std :: wstring的某种原始值,这可在我的机器上运行:
#include <boost/serialization/split_free.hpp>
...
namespace boost {
namespace serialization {
template<class Archive>
void load(Archive & ar,JuceString & j,const unsigned int version)
{
std::wstring tmp;
ar & boost::serialization::make_nvp(\"value\",tmp);
j = tmp;
}
template<class Archive>
void save(Archive & ar,const JuceString & j,const unsigned int version)
{
const std::wstring tmp(j.toWideCharPointer());
ar & boost::serialization::make_nvp(\"value\",tmp);
}
} // namespace serialization
} // namespace boost
BOOST_SERIALIZATION_SPLIT_FREE(JuceString)
这样就不必编写operator >>
,而使boost处理直接将wstring读/写到存档中。您也只需编写一次,这样就避免了重复问题,然后您可以随意使用often13ѭ。
,我不知道是否有答案,但是在比较工作区中的代码以序列化ATL CString时,我有以下内容:
inline void serialize(Archive & ar,CString & s,const unsigned int file_version)
{
std::wstring ss( s );
ar & BOOST_SERIALIZATION_NVP(ss);
s = ss.c_str();
}
我想知道您是否可以在ѭ15中做类似的事情-不确定此解决方案是否适用于您。如果没有的话,请提前道歉。