ROOT, CINT and STL

From: Alexander Zvyagin (zvyagin@mx.ihep.su)
Date: Wed Feb 10 1999 - 04:53:36 MET


Date: Wed, 10 Feb 1999 11:05:49 +0000
From: Alexander Zvyagin <ZVYAGIN@mx.ihep.su>
X-Sender: ZVYAGIN@polar.ihep.su
To: Frederic MACHEFERT <machefer@hep.saclay.cea.fr>
cc: roottalk@hpsalo.cern.ch
Subject: ROOT, CINT and STL
Message-ID: <Pine.VMS.3.91-b11-vms.990210105447.3452A-100000@polar.ihep.su>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII

Dear friends,

On Tue, 9 Feb 1999, Frederic MACHEFERT wrote:

> 	Hi, 
> 
>   I would like to use the vector class from the standard template library.
> Is it possible to create a shared library (and a dictionary) using the
> vector class, and can I use this library in cint ? If it is not possible
> can I create an executable including root libraries and the vector class.

Yes. It is possible.

The idea is that ROOT and CINT should not know 
anything  about your STL objects. In header files use directive
"#ifndef __CINT__" (or similar) to hide all STL-parts, and write your 
own Streamer function(s) for ROOT class(es). You must write also your own 
functions to get access to STL data members from CINT.

Below is simple example how ROOT may work with STL.
Just extract files from this mail and test.

With best wishes,
Alexander.


--- File Event.h ---------------------------------------
#ifndef Event___include
#define Event___include

// --- ROOT ---
#include "TObject.h"

#ifndef __CINT__
// --- STL ---
#include <pair.h>
#include <vector.h>
#endif // __CINT__

////////////////////////////////////////////////////////////////////////////////

class Event : public TObject
{
  public:

    virtual            ~Event     (void) {}
                        Event     (void) {}

    void                SetA      (Bool_t a1,Int_t a2);
    void                AddToB    (Double_t b);
    void                Print     (const Option_t *opt="") const;

    #ifndef __CINT__
    pair<Bool_t,Int_t>  fA;
    vector<Double_t>    fB;
    #endif // __CINT__

  ClassDef(Event,1)                         // Event with STL
};

////////////////////////////////////////////////////////////////////////////////

#endif // Event___include

--- File Event.c ---------------------------------------------------

// --- Standard C/C++ library ---
#include <stream.h>

// --- Internal files ---
#include "Event.h"

ClassImp(Event)

////////////////////////////////////////////////////////////////////////////////

void Event::SetA(Bool_t a1,Int_t a2)
{
  fA = make_pair(a1,a2);
}

////////////////////////////////////////////////////////////////////////////////

void Event::AddToB(Double_t b)
{
  fB.push_back(b);
}

////////////////////////////////////////////////////////////////////////////////

void Event::Print(const Option_t *opt) const
{
  cout << "fA = (" << (fA.first==kTRUE ? "true" : "false")
       <<       "," << fA.second << ")\n";
  cout << "fB: size=" << fB.size() << " (";
  copy(fB.begin(), fB.end(), ostream_iterator<Double_t>(cout," "));
  cout << ")\n";
}

////////////////////////////////////////////////////////////////////////////////

void Event::Streamer(TBuffer &R__b)
{
  if( R__b.IsReading() )
  {
    Version_t R__v = R__b.ReadVersion(); if (R__v) { }

    R__b >> fA.first;
    R__b >> fA.second;

    UInt_t fB_size;
    R__b >> fB_size;
    while( fB_size-- > 0 )
    {
      Double_t b;
      R__b >> b;
      fB.push_back(b);
    }
  }
  else
  {
    R__b.WriteVersion(Event::IsA());

    R__b << fA.first;
    R__b << fA.second;

    R__b << (UInt_t)fB.size();
    for( vector<Double_t>::const_iterator it = fB.begin();
         it != fB.end();
         it++ )
      R__b << *it;
  }
}

--- File rootlogon.C  (example) -------------------------------------

void rootlogon(void)
{
  gSystem->Load("Event.so");
  Event e;
  printf("\nEmpty event:\n");
  e.Print();
  e.SetA(kTRUE,11);
  e.AddToB(1.1);
  e.AddToB(-1);
  e.AddToB(1e99);
  e.AddToB(9e99);
  e.AddToB(-4e321);
  printf("\nSomething:\n");
  e.Print();
  
  printf("\nWriting...\n");
  TFile f1("event.root","RECREATE","",9);
  e.Write("e");
  f1.Close();
  
  printf("Reading...\n");
  TFile f2("event.root");
  Event *e_ptr = (Event *) f2.Get("e");
  printf("\nEvent:\n");
  e_ptr->Print();
}

--- File LinkDef.h --------------------------------
#ifdef __CINT__

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

#pragma link C++ class Event-;

#endif

--- File Makefile -----------------------------------

INCLUDE         = -I/usr/local/include -I$(ROOTSYS)/include

CXXFLAGS        = -fno-rtti -fno-exceptions -O $(INCLUDE)

.c.o:
		$(CXX) $(CXXFLAGS) -c $*.c -o $*.o

##########################################################################################

headers         = Event.h
classes         = $(headers:.h=.c)
Cint            = $(headers) LinkDef.h
SRC             = $(classes) Cint.c
OBJ             = $(SRC:.c=.o)

##########################################################################################

Event.so:	$(OBJ)
		$(CXX) -O -shared -o Event.so $(OBJ)

Cint.c:		$(Cint)
		rootcint -f Cint.cxx -c $(INCLUDE) $(Cint)
		@mv Cint.cxx Cint.c

clean:
		@rm -fr core *.bck *.bak *.o *.so *.rz *.root *.log *.out \
		*.dvi *.aux \
		*Cint.[ch] *Cint.cxx html

depend:
		@makedepend -I$(INCLUDE) *.c >& /dev/null



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:29 MET