我正在使用 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 已被“分解”,这当然会导致“输入流错误”异常。
最奇怪的是,直到一周前我才开始工作... :( 我不知道是什么让它现在不起作用...
编辑:显示重现行为的一个小示例代码,唯一的依赖是 boost :
#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;
}
这将确保字符串被正确解析。
关于c++ - 使用 XML 宽存档 boost juce::String 的反序列化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6126133/