Load a Class, Difference between Root5 and Root6

I notice a difference in loading a new compiled Class with Root 5 and Root 6.
In Root 5 is possible to write a script loading a Class and use it in same script.
In Root 6 , i didn’t success to use a unique script. I had to load the class in a first script and use it in a second script called by the first.
Is possible to do use a unique script with Root 6 ?


Exemple : Files used

Script used with Root 5 :

{  // Script.C
  gROOT->Reset(); 
  gROOT->ProcessLine(".L  $ROOTSYS/lib/libHist.so");
  gROOT->ProcessLine(".L ./TUser_C.so"); //load TUser class  
  
  TUser * a= new TUser();          // creat user object
  
  a->InitUser();
  a->User();                       
  a->User();     
  a->EndUser();
  gROOT->ProcessLine(".q");
}


Scripts used with Root6

{  // Script1.C
  gROOT->Reset();      
  gROOT->ProcessLine(".L  $ROOTSYS/lib/libHist.so");
  gROOT->ProcessLine(".L ./TUser_C.so"); //load TUser class 
  gROOT->ProcessLine(".x ./Script2.C");
}


{// Script2.C  

  TUser * a= new TUser();          // creat user object
  
  a->InitUser();
  a->User();                       
  a->User();     
  a->EndUser();
  gROOT->ProcessLine(".q");
}


// File :  TUser.h

#ifndef __TUser__
#define __TUser__
#include "stdio.h"
#include <TNamed.h>
#include <TH1.h>

class TUser : public  TNamed{

 protected:
  int fVerbose;             
       
  TH1I *fMyHisto ;

 public:
  TUser() ;   // default constructor of TUser object 
  ~TUser() ; 
  
  virtual void InitUser();
  virtual void User();
  virtual void EndUser();
  ClassDef (TUser ,1); // User Treatment of Data
};


// File : TUser.C

#include "./TUser.h"
#include "TROOT.h"

ClassImp (TUser);

TUser::TUser ()
{
  // Constructor
printf(" Constructor of TUser\n");
}

TUser::~TUser()  {
  //Destructor of class TUser
  if (fMyHisto)
  delete fMyHisto;
 printf(" Destuctor of TUser\n");
}

void TUser::InitUser(){
  // Initialisation for   user 
 fMyHisto = new TH1I ("MyHisto","MyHisto",1024,0,1024);
 printf(" Init TUser\n");
}

void TUser::User() {
 fMyHisto->Fill(1);
 printf(" Fill histo\n");
}

void TUser::EndUser() {
 printf(" End of  TUser\n");
}


# Makefile for the ROOT test programs.

CLASSNAME   := TUser
TUserDIR     := ./


# Extensions des fichiers
ObjSuf        = o
SrcSuf        = C
ExeSuf        =
DllSuf        = so
OutPutOpt     = -o 

# Compilateur et options
CXX	= g++ 
LD 	= g++ 
ifeq ($(COMPILER),CLANG)
CXX	= clang++	
LD 	= clang++	
endif
CXXFLAGS      = -O -Wall -fPIC
LDFLAGS       = -O
SOFLAGS       = -shared

# Options de ROOT
ROOTCFLAGS   := $(shell root-config --cflags) -I$(ROOTSYS)/xmlparser/inc -I$(ROOTSYS)/io/xmlparser/inc
ROOTLIBS     := $(shell root-config --libs) -lHtml -lSpectrum
ROOTGLIBS    := $(shell root-config --glibs)

CXXFLAGS     += $(ROOTCFLAGS) 
LIBS          = $(ROOTLIBS)  $(SYSLIBS)
GLIBS         = $(ROOTGLIBS) $(SYSLIBS)

#------------------------------------------------------------------------------
SHARELIB      = $(CLASSNAME)_C.so 
#------------------------------------------------------------------------------
all:  $(SHARELIB)

$(CLASSNAME)_C.so: $(CLASSNAME).o   $(CLASSNAME)Dict.o	
	$(LD) $(SOFLAGS) $^ $(OutPutOpt) $@

$(CLASSNAME)Dict.C:	$(CLASSNAME).h
			@echo "Generating dictionary $@..."
			rootcint -f $@ -c -p $(CXXFLAGS) $(INCLIST) $^ $(CLASSNAME)_linkdef.h

clean:
	@echo "Clean :  rm -f core  *.o *Dict* *.so"
	@rm -f core  *.o *Dict* *.so


.SUFFIXES: .$(SrcSuf)

###

.$(SrcSuf).$(ObjSuf):
	$(CXX) $(CXXFLAGS) -c $<

# dependances
$(CLASSNAME).o:	$(CLASSNAME).C	 $(CLASSNAME).h


//TUser_linkedef.h
#ifdef __CINT__

#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class TUser;
#endif


//.rootrc
Plugin.TNamed:  GuserPlugin  TUser   ./TUser.C+  "TUser()"


Luc

Hi Luc,

I think this is not possible. The reason behind this change in behaviour is that CINT works more like a “parser”, processing line by line the macro while CLING is backed by a real compiler. This implies that in ROOT6 all the lines the macro are considered a single entity and it is not possible to resolve missing symbols at compile time with a library which is loaded at runtime. In some sense, it is “too late”.

One way in which you can obtain a similar result is to create a rootmap for your dictionary. You simply add to your present rootcling/rootcint invocation these two switches: -rml TUser_C.so -rmf TUser_C.rootmap (note that the libraries usually start with the prefix lib by convention).
The rootmap file will allow ROOT to automatically load the required library and automatically parse the headers which contain its interface.

Let us know how it goes.

Cheers,
D

For ROOT6, change your ROOT5 script as follows:

// Script.C
R__LOAD_LIBRARY(libHist)
R__LOAD_LIBRARY(TUser_C)
void Script() {
  TUser * a= new TUser(); // creat user object
  a->InitUser();
  a->User();
  a->User();
  a->EndUser();
  gApplication->Terminate();
}

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.