ROOT, CINT and STL

Alexander Zvyagin (zvyagin_at_mx.ihep.su)
Wed, 10 Feb 1999 11:05:51 GMT+03:00


Date: Wed, 10 Feb 1999 11:05:49 +0000
From: Alexander Zvyagin <ZVYAGIN_at_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