Skip to content

auto serializer for C++11, Do you want to update your classes easily ?

License

Notifications You must be signed in to change notification settings

yossi-tahara/Theolizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

リンク:【Theolizer公式サイト】【サポート掲示板】【使い方解説】

-- 目次 --

1.Theolizerとは
2.Theolizerの特長
3.対応環境
4.その他

1.Theolizerとは

皆さんは C++ でデータをファイルへ保存したりシリアル通信等で他のコンピュータへ送ったりする時、どのようにしていますか?
多くの人は、保存や通信用のデータ・フォーマットを設計し、そのフォーマットへ変換/逆変換するプログラムを1つ1つ書いていると思います。
Theolizerはその手間をズバッと無くすC++開発ツールです。シリアライザと呼ばれます。
(C言語+αの知識で使えるよう設計していますのでベターCerの方にもお使い頂けます。)

例えば、ある構造体をファイルへ保存/回復する時、最初に次のような処理が考えられます。

#include <iostream>
#include <fstream>
#include <string>

struct Foo
{
    std::string name;
    int age;

    void save(std::ostream& os) {os << name << " " << age << "\n";}
    void load(std::istream& is) {is >> name >> age;}
};

int main()
{
    {
        Foo foo;
        foo.name="Taro Yamada";
        foo.age=22;

        std::ofstream ofs("sample.txt");
        foo.save(ofs);
    }
    {
        Foo foo;
        std::ifstream ifs("sample.txt");
        foo.load(ifs);

        foo.save(std::cout);	// 回復結果を簡易表示
    }
}

sample.txt

Taro Yamada 22

しかし、残念なことに これはバグってます。nameには性と名があり、間を空白文字で区切ります。従って、保存はされますが、回復する時、nameに名前の前半のみ回復され後半はageへ回復しようとして失敗します。
そこで、例えばnameとageをそれぞれ1行へ保存することにし下記のようにsave/loadを修正することも考えられます。

struct Foo
{
    std::string name;
    int age;

    void save(std::ostream& os) {os << name << "\n" << age << "\n";}
    void load(std::istream& is)
    {
        std::getline(is, name);
        std::string temp;
        std::getline(is, temp);
        age=atoi(temp.c_str());
    }
};

sample.txt

Taro Yamada
22

フィールド区切り方法を検討し、実装するので意外に手間がかかります。そして通常は保存/回復したいデータはもっと複雑です。
色々工夫して手間を省くとは思いますが、その工夫そのものにも手間がかかります。

Theolizerを使った場合:
まずTheolizerライブラリが基本的な保存/回復ライブラリを提供します。(全ての基本形+全てのstd::basic_string型に対応)更に、ほとんどの場合 Theolizerドライバがクラスのメンバ変数を自動的に列挙し、保存/回復処理を生成します。あなたはその保存/回復処理を呼び出すだけです。

サンプル・ソース(example.cpp)

#include <iostream>
#include <fstream>
#include <string>
#include <theolizer/serializer_json.h>

struct Foo
{
    std::string name;
    int age;
};

#include "example.cpp.theolizer.hpp"            // Theolizer自動生成先

int main()
{
    // 保存
    {
        Foo foo;
        foo.name="Taro Yamada";
        foo.age=22;

        std::ofstream ofs("sample.txt");
        theolizer::JsonOSerializer<> jos(ofs);  // シリアライザを生成
        THEOLIZER_PROCESS(jos, foo);            // ファイルへfooを保存
    }

    // 回復
    {
        Foo foo;
        std::ifstream ifs("sample.txt");
        theolizer::JsonISerializer<> jis(ifs);  // デシリアライザを生成
        THEOLIZER_PROCESS(jis, foo);            // ファイルからfooを回復

        theolizer::JsonOSerializer<> jos(std::cout);
        THEOLIZER_PROCESS(jos, foo);            // 回復結果の簡易表示
    }
}

構造体Fooのメンバを保存/回復する処理をTheolizerが自動生成しますので、あなたは記述する必要がありません。

sample.txt

{
    "SerialzierName":"JsonTheolizer",
    "GlobalVersionNo":1,
    "TypeInfoList":[1]
}
{
    "name":"Taro Yamada",
    "age":22
}

example.cppをビルドする手順

  1. Theolzierのダウンロードとインストール
  2. ビルド環境の自動生成(by CMake)とビルド

CMakeプロジェクトを作ってTheolizerを組み込む方法

公式サイトの技術ブログで解説しています。
CMakeの基礎から解説していますので、CMakeの使い方を学びたい方も是非ご覧になって下さい。


2.Theolizerの特長

C#のようにリフレクションを提供する言語なら可能ですか、C++はそのような機能を提供しておらず、我々のC++プログラムがクラスのメンバ変数のリストを得ることができません。(C++コンパイラは持っている情報ですので扱えそうな気もして、かなり深く調べましたが残念ながらできません。)

それを clangのlibToolingの力を借りてできるようにしました。これにより、C++コンパイラが持っているクラスのメンバ変数リストとenum型のシンボル名を取り出して、自動シリアライズを実現しました。

そのTheolizerは、次のような特長を持っています。

2-1.自動シリアライズ

TheolizerはClang/LLVMに含まれるlibToolinglibToolingの構文解析機能を用いてクラスやenum型の定義を解析し、メンバのリストを自動生成します。これにより、クラスやenum型を変更した時もメンバ・リストへの反映漏れが無く、プログラム開発が捗ります。

クラスのメンバ変数を保存する時、異なるファイルへ保存したい時もあると思います。一部のメンバ変数(ファイル・ハンドル等)は保存しないでしょうし、一部のメンバ変数は設定ファイルへ保存し、また別のメンバはデータ・ファイルへ保存したいというケースは少なくないと思います。

TheolizerはclangのAnnotation機能を使ってメンバ変数に保存先を指定することで、クラスを分割して異なるファイルへ保存したり、一部を通信で他のプログラムへ送信したり、一部はそもそも保存しないことができます。

一般に、ポインタをファイルへ保存し、プログラムを再起動した後で回復しても意味はありません。

Theolizerはポイント先を一緒にファイルへ保存してオブジェクト追跡することでポインタを回復することができます。これにより非常に複雑なデータ構造を容易に保存/回復・送受信できます。

2-4.プログラム変更対応

シリアライザを使って保存するということは、内部データの構造を保ったままファイルへ保存するということです。内部データ構造はプログラムの変更に伴い変更されるため、旧プログラムで保存されたファイルを回復できるようにするためには内部データ構造の変更に強い制限がかかります。

Theolizerはその制限を大幅に緩和しました。

  • クラス定義enum定義の変更
    クラスのメンバ変数の追加/削除/順序変更、および、メンバ変数名の変更に対応します。
    enum型のシンボルの追加/削除/順序変更、および、シンボル名やシンボル値の変更に対応します。

  • クラスについてバージョン・アップ/ダウン処理を記述可能
    クラスをバージョン・アップする際に行いたい処理を記述できます。
    (例えば、変数にオフセットを追加した時、そのオフセットを加える処理など)
    また、旧バージョン形式で保存したい場合はバージョン・ダウン処理を記述できます。
    (例えば、オフセットを引く処理など)

  • バージョン・アップ/ダウンをカスケードに処理します
    例えば、Ver.4をVer.5へバージョンアップした時、従来はVer.4→Ver.5のプログラム開発だけでなく、Ver.1~Ver.3→Ver.4のプログラムをVer.1~Ver.3→Ver.5へ改造する必要がありました。
    Theolizerはバージョン・アップ/ダウン処理をカスケード(Ver.1→Ver.2→Ver.3→Ver.4→Ver.5)に行いますので、Ver.4→Ver.5のプログラムを開発するだけで済みます。
    これによりバージョンが上がった時のプログラム開発を大きく低減できます。


3.対応環境

マルチ・プラットフォームとC++11規格コンパイラに対応できるよう設計しています。
現時点でテストできている環境はWindowsとubuntuです。

OS C++コンパイラ
Windows 10 Professional 64bit Visual Studio C++ 2017 Community update 3
MinGW 7.1.0 32bit posix dwarf(mingw-w64-install.exe)
MinGW 7.1.0 64bit posix seh(mingw-w64-install.exe)
ubuntu 16.04 LTS 64bit gcc 5.4.0(Ubuntu 5.4.0-6ubuntu1~16.04.2)

将来的にはマッキントッシュOS Xにも対応する予定です。


4.その他

4-1.詳細ドキュメント

詳細なドキュメントをhttp://doc.theolizer.comに置いています。
また、Theolizerをインストールした時、インストール先のdocフォルダにもあります。

4-2.プリビルド版

Windowsとubuntu用のプリビルド版を用意しています。
当リポジトリのrelasesからダウンロードして下さい。

4-3.自動テスト

Theolizerは信頼性を上げるために自動テストを実装しています。

  • CIサービスによるサブセット・テスト(masterブランチの最新版)の状態
    Travis CIにてubuntu環境のサブセット・テストをpush毎に自動実行しています。
    Travis CI result : Build Status "for StaticWithBoost without sudo on ubuntu 14.04 LTS"

  • ローカル環境によるフルセット・テストについて
    バージョン番号に-Prereleaseサフィックスのないものはフルセットのテストを完了しています。
    フルセット・テストの実行と共にプリビルド版を生成しています。これにvX.Y.Zのタグをつけて当リポジトリのrelasesへ登録します。

4-4.不具合報告を頂く時のお願い

不具合報告は他の報告同様、当リポジトリのIsshuesへお願いします。
不具合をできるだけ遅滞なく伝達できるよう下記の点に注意を払って頂けると助かります。
全て守って頂きたいという意味ではなく可能な部分についてご配慮頂けることをお願い致します。

  1. 他のIssuesをチェックして同様な不具合報告がないか探して下さい
    もし、見つかった場合、あなたの環境で発生した旨の追記をそのIssueへお願いします。
    不具合が発生している人数も対策優先順位を決める際の参考となりますので。
  2. できるだけ具体的なタイトルを付けて下さい
    他の方も同じ不具合の発生を探しやすいように、できるだけ どの部分のどんな不具合か分かるようなタイトルを付けて下さい。
  3. 不具合発生環境を記載下さい
    下記情報の記載をお願い致します。
    • Theolizerの種類
      プリビルド版ならどのプリビルド版か。
      ソース版ならビルドに用いたコンパイラ、LLVMのバージョン、boostのバージョン。
    • OSの種類とバージョン、32bit or 64bit
    • コンパイラの種類とバージョン、32bit or 64bit
    • CMakeのバージョン、32bit or 64bit
  4. 下記不具合情報をできるだけご記載下さい
    • 不具合発生時に行っていた操作
      例えば、Theolizerを用いたあなたのプログラムのビルド中など
    • どのような現象が発生したか?
    • 期待する動作はなにか?
    • 不具合が発生するソース・コード
      できれば、不具合が発生する最小のソースをご提供頂ければ助かります。
  5. その他、追加情報があれば記載下さい
    何か気になったことや、不具合原因の推測等、なんでもよいので関連しそうな追加情報を頂けると助かります。

© 2016 Theoride Technology All Rights Reserved.
"Theolizer" is a registered trademark of Theoride Technology.