自作クラスをrootのsystemに組み込むにはTObjectを継承する必要がある。このことで例えば下のような恩恵をうけることができる。
もちろん、こうした機能を組み込まず、一般的なc++のクラスを定義することもできる。その場合はここに書かれていることは気にしなくていい。
例として、下のようなクラスを作ろう
#ifndef __MYCLASS__ #define __MYCLASS__ #include <TObject.h> #include <iostream> class MyClass : public TObject { public: MyClass(); //デフォルトコンストラクタは必須 int Get(); void Set(int); ClassDef(MyClass,1); protected: int f; }; #endif
#include "MyClass.h" #include <TObject.h> #include <iostream> ClassImp(MyClass) MyClass::MyClass() : f(0){ //デフォルトコンストラクタでメンバ変数にメモリ確保をしてはいけない、らしい・・・ }; int MyClass::Get(){ return f; }; void MyClass::Set(int a){ f = a; };
ポイントは
rootで自作クラスを使用するためにはDictionaryにクラスを登録する必要がある(?)。
まず次のようなファイルを生成する。
#ifdef __CINT__ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class MyClass+; #endif
さきほど作成したクラスのヘッダーMyClass.hとLinkDef.hを使い、下のようにコマンドすると、MyClassDict.cxxが生成される。
rootcint -f MyClassDict.cxx -c MyClass.h LinkDef.h
ここでLinkDef.hはコマンドの最後にくる必要がある。
あとはMyClassDict.cxxと一緒にクラスの実装コードを普通にコンパイルすればいい。
g++ `root-config --cflags --libs` -shared MyClassDict.cxx MyClass.cxx -o libmyclass.so
ACLiCを使う場合はheaderの最後にpragma statementを加えるだけでいい。らしい。
#ifndef __MYCLASS__ #define __MYCLASS__ #include <TObject.h> #include <iostream> class MyClass : public TObject { public: MyClass(); int Get(); void Set(int); ClassDef(MyClass,1); protected: int fConst; }; #endif #ifdef __MAKECINT__ #pragma link off all globals; #pragma link off all classes; #pragma link off all functions; #pragma link C++ class MyClass+; #endif
あとは普通にACLiCでコンパイルすればいい。
[ ] .L MyClass.cxx+
cintでマクロを読ませる場合はDictionaryを作らずとも自作クラスが使用可能(理由は理解できてない)。
ただし、そのクラスをファイルに保存しても、なぜかクラスの種類はTObjectとして保存されてしまう。
いまいちDictionaryの仕組みが理解できていない。
http://root.cern.ch/root/Version516.news.html
rootでは例えばTH1などのクラスを使用するときにライブラリをリンクする必要はない。これはクラスを使用するときに自動的にライブラリを読み込むという仕組みをとっているからである。
自作したクラスについてもライブラリを自動的に読み込むようにするにはrootmapを作る必要がある。
rootmapはクラスとライブラリとの対応関係を記述したファイルで、$ROOTSYS/libに.rootmap拡張子のファイルがおいてあるのが確認できると思う。
作り方は例えば、myclassのライブラリがlibmyclass.soで更にlibHist.soに依存している場合は以下のようにする。
rlibmap -f -o $lib/libmylib.rootmap -l $lib/libmyclass.so -d libHist.so -c $include/Linkdef.h
libmylib.rootmapを見てみると下のような単純なファイルであることがわかる。
Library.MyClass: libmyclass.so libHist.so
なので、自分で直接編集して作ってもいいと思う。