できたっぽい。
CStringPack.h
#ifndef MSGPACK_TYPE_MFC_CSTRING_INCLUDE #define MSGPACK_TYPE_MFC_CSTRING_INCLUDE #include "msgpack/object.hpp" #include <string> #include "StringUtil.h" // ToMultStr, ToWideStr namespace msgpack { inline CStringW& operator>> (object o, CStringW& v) { if(o.type != type::RAW) { throw type_error(); } std::string s; s.assign(o.via.raw.ptr, o.via.raw.size); v = ToWideStr(s).c_str(); return v; } template <typename Stream> inline packer<Stream>& operator<< (packer<Stream>& o, const CStringW& v) { const std::string s = ToMultStr(static_cast<LPCTSTR>(v)); o.pack_raw(s.size()); o.pack_raw_body(s.data(), s.size()); return o; } inline void operator<< (object::with_zone& o, const CStringW& v) { o.type = type::RAW; const std::string s = ToMultStr(static_cast<LPCTSTR>(v)); char* ptr = (char*)o.zone->malloc(s.size()); o.via.raw.ptr = ptr; o.via.raw.size = (uint32_t)s.size(); memcpy(ptr, s.data(), s.size()); } inline void operator<< (object& o, const CStringW& v) { const std::string s = ToMultStr(static_cast<LPCTSTR>(v)); o.type = type::RAW; o.via.raw.ptr = s.data(); o.via.raw.size = (uint32_t)s.size(); } } // namespace msgpack #endif // MSGPACK_TYPE_MFC_CSTRING_INCLUDE
#include "stdafx.h" #include <msgpack.hpp> #include "CStringPack.h" #include <vector> #include <string> #include <iostream> #include <fstream> #include <boost/range/algorithm/for_each.hpp> #include <boost/bind.hpp> class Data { int id; CStringW name; public: Data() : id(0) {} Data(int id, const CStringW& name) : id(id), name(name) {} void print() const { std::cout << id << std::endl; AfxMessageBox(name); } MSGPACK_DEFINE(id, name); }; int main() { // シリアライズ { std::vector<Data> vec; vec.push_back(Data(1, L"abc")); vec.push_back(Data(2, L"あいうえお")); std::ofstream file("data.mpac"); msgpack::pack(&file, vec); } // デシリアライズ { std::ifstream file("data.mpac"); std::istreambuf_iterator<char> first(file); std::istreambuf_iterator<char> last; const std::string data(first, last); try { msgpack::unpacked msg; msgpack::unpack(&msg, data.data(), data.size()); msgpack::object obj = msg.get(); const std::vector<Data> vec = obj.as<std::vector<Data> >(); boost::for_each(vec, boost::bind(&Data::print, _1)); } catch (msgpack::unpack_error&) { std::cout << "unpack failed" << std::endl; } catch (msgpack::type_error&) { std::cout << "type error" << std::endl; } } }
ToMultStr, ToWideStrはこちらを参照:
MFC/ATL - std::stringとstd::wstringの相互変換