Adding Your Own Classes to ROOT via Shared Libraries.

 First of all there is ROOT HOWTO's  pages  and ROOT Tutorials  on subject and
related issues:


Below is description of my own experience:

  1. Every your own base class should be appeared in ROOT must be derived from ROOT's class TObject. In the case of WAT there is only one base class Wavelet, so that description of class Wavelet should look like:
  2. class Wavelet : public TObject

  3. At the very end of class description there should be included ROOT's macro ClassDef with class name as first parameter and class version ID as second parameter (0 or 1), selecting 1 is good in most cases. For explanation of this parameter see Adding Your Own Classes to ROOT
  4. ClassDef(Wavelet,1)

    So that the minimum header file for Wavelet class should look like:
    wavelet.h


    #include "TObject.h"
    class Wavelet : public TObject
    {
    public:

      Wavelet(); // Constructor
       ~Wavelet(); // Destructor
       ClassDef(Wavelet,1)
    };

  5. Before the code body of first class member the ROOT's macro ClassImp() must be included. The minimal file wavelet.cc should look like:
    #include "wavelet.h"
    ClassImp(Wavelet)
    Wavelet::Wavelet() {} // Constructor
    Wavelet::~Wavelet() {} // Destructor
  6. All classes derived from Wavelet must use macros ClassDef() and ClassImp() in the same way.

  7. To create shared library your source code must be compiled as PIC (position independent code) , this is accomplished by option -fPIC for g++ . We use GNU gcc version 2.95.2 built with options --with-gnu-ld, --with-gnu-as, --enable-shared, --enable-threads. Do not forget to add to the compiler options the reference to ROOT's include directory: -I ${ROOTSYS}/include, usually.
  8. To create shared library for ROOT the dictionary files should be generated for your code. This may be accomplished by command

    rootcint -f wave_dict.cc -c < list of all header files >

    This command will generate files wave_dict.cc and wave_dict.h which also must be compiled with the same options as you own code.

    To have more control on dictionary generation I created the file wavelet_LinkDef.h (xxx_LinkDef.h is a required style) which contains:

    wavelet_LinkDef.h


    #ifdef __CINT__

    #pragma link off all globals;
    #pragma link off all classes;
    #pragma link off all functions;

    #pragma link C++ class Wavelet;
    #pragma link C++ class WaveData-;
    #pragma link C++ class WaveDataTD;
    #pragma link C++ class WaveDataWD;
    #pragma link C++ class WaveTool;
    #pragma link C++ class WaveLifting-;
    #pragma link C++ class WaveLiftingBiort;
    #pragma link C++ class WaveLiftingBiortInt;
    #pragma link C++ class WaveDataZ-;

    #endif

    It's contents looks cryptic, but it works. All your classes should be listed here. Minus sign after class name means that this class has custom (i.e. written by me) function Streamer() (look How to Write Objects to a File for details). This file must be at the end of list of header files in command string for rootcint.

  9. After compilation of all parts of code the shared library may be created via command (we use GNU ld and our gcc and g++ are built with option --with-gnu-ld) :

    ld -shared -o wavelet.so < list of all PIC files >

  10. Now check if shared library work. Start interactive root session and load the library by command:

       root [0] gSystem->Load("wavelet.so");

    Check if your class is available by command:

       root [1] .class Wavelet

    If everything right you should get something like:

    ===========================================================================
      class Wavelet //Wavelet Base Class
      size=0xc
      (tagnum=464,voffset=-1,isabstract=0,parent=-1,gcomp=0,=~cd=0)
      List of base class--------------------------------------------------------
      0x0 public: TObject //Basic ROOT object
      List of member variable---------------------------------------------------
      Defined in Wavelet
      0x0 private: static TClass* fgIsA
      List of member function---------------------------------------------------
      filename line:size busy function type and name (in Wavelet)
      (compiled) 0:0 0 public: Wavelet Wavelet(void); //Constructor
      (compiled) 0:0 0 public: const char* DeclFileName(void);
      (compiled) 0:0 0 public: int DeclFileLine(void);
      (compiled) 0:0 0 public: const char* ImplFileName(void);
      (compiled) 0:0 0 public: int ImplFileLine(void);
      ....
     


Last update: May 25, 2000
Andrei Sazonov