C++構造体とXML

概要

前章で紹介した cereal は、xmlも取り扱うことができます。

C++構造体とJson

  • C++側のソース

    XmlCereal.dllとしてコンパイル
    #include <windows.h>
    #include <string>
    #include <iostream>
    
    #include "HmCppInvoke.h"
    
    #include <cereal/cereal.hpp>
    #include <cereal/archives/xml.hpp>
    
    
    
    using namespace Hidemaru;
    using namespace std;
    
    
    struct Person {
        std::string name;
        int year = 0;
    
        template<class Archive>
        void serialize(Archive& archive)
        {
            archive(CEREAL_NVP(name), CEREAL_NVP(year));
        }
    };
    
    extern "C" __declspec(dllexport) THmNumber test() {
        Hm.funcDllExport();
    
        try {
    
            Person person_out;
            person_out.name = "Komiyamma";
            person_out.year = 48;
    
            std::stringstream ss;
    
            // ★ここでカッコ必須。
            // 理由は、ssの中身を参照するまでに、以下のo_archiveオブジェクトのライフサイクルが必ず終了している必要があるため。
            {
                cereal::XMLOutputArchive o_archive(ss);
                o_archive(cereal::make_nvp("root", person_out));
            }
    
            // Jsonへ
            wstring wss = Text::Encoding::utf8_to_utf16(ss.str());
            Hm.OutputPane.output(wss + L"\r\n");
    
            // Jsonからの読み込み(istream系ならなんでも)
            Person person_input;
            {
                cereal::XMLInputArchive i_archive(ss);
                i_archive(cereal::make_nvp("root", person_input));
            }
    
            int year = person_input.year;
            string name = person_input.name;
            Hm.OutputPane.output(L"year:" + to_wstring(year) + L"\r\n");
            Hm.OutputPane.output(L"name:" + Text::Encoding::utf8_to_utf16(name) + L"\r\n");
        }
        catch (exception& e) {
            // エラー内容をchar → wstring へ
            auto wide_what = Text::Encoding::cp932_to_utf16( e.what() );
            Hm.OutputPane.output(wide_what + L"\r\n");
        }
    
    
        return 1;
    }
    
  • 秀丸マクロ側のソース

    test.mac
    // XmlCereal.dllとしてコンパイルした
    #dll = loaddll(currentmacrodirectory + @"\XmlCereal.dll");
     
    // 途中でマクロの文法や型の致命的エラーが発生した場合でもdllを解放する。
    if (version >= 898) { eval "keepdll #dll, 0"; }
     
    #r = dllfuncw(#dll, "test");
     
    freedll(#dll);