Dear Rooters
I need to call functions with variable arguments from a macro.
I have written two test files:
1, A macro "macroTestParams.C" (see below), which works ok.
2, A compiled library "libTestClass.so" (all files are shown below)
which I call from a macro ""macroTestClass.C"
Sorrowly, in the second case, the variable function can be called
from inside the class but not from the macro.
I get a limitation warning as seen in the following output:
*******************************************
* *
* W E L C O M E to R O O T *
* *
* Version 3.00/06 12 March 2001 *
* *
* You are welcome to visit our Web site *
* http://root.cern.ch *
* *
*******************************************
CINT/ROOT C/C++ Interpreter version 5.14.79, Feb 24 2001
Type ? for help. Commands must be C++ statements.
Enclose multiple statements between { }.
root [0] .L macroTestClass.C
root [1] run()
------TTestClass::TTestClass------
------TTestClass::FInitTest------
------TTestClass::FInit------
vParams[0] = 0.2
vParams[1] = 3.4
vParams[2] = 1.6
vParams[3] = 4.7
Limitation: Variable argument is not supported for this platform FILE:
macroTestClass.C LINE:14
------TTestClass::FInitTest------
------TTestClass::FInit------
vParams[0] = -2.35344e-185
vParams[1] = nan
vParams[2] = 5.81295e-234
vParams[3] = nan
*** Interpreter error recovered ***
root [2] .q
Could you please tell me if I am doing someting wrong?
If not, how can I overcome this problem?
If this is a limitation of CINT, will this be solved in a future
version?
My system: PowerBook running LinuxPPC 2000
root 3.00/06 12 March 2001
Thank you in advance for your help.
Best regards
Christian
----------------------------------
C.h.r.i.s.t.i.a.n S.t.r.a.t.o.w.a
V.i.e.n.n.a, A.u.s.t.r.i.a
//==================================================================
// macroTestParams.C
//==================================================================
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#include <iomanip.h>
//#ifndef ROOT_Varargs
#include "Varargs.h"
//#endif
void testparameters(Int_t vNPars, ...)
{
Double_t *vParams = new Double_t[vNPars];
// get parameters
va_list vArgPtr;
va_start(vArgPtr,vNPars);
for (Int_t i=0;i<vNPars;i++) {
vParams[i] = va_arg(vArgPtr,Double_t);
}//for_i
va_end(vArgPtr);
for (Int_t i=0;i<vNPars;i++) {
cout << "Params[" << i << "] = " << vParams[i] << endl;
}//for_i
testpars(vNPars,vParams);
delete [] vParams;
}
void testpars(Int_t vNPars, Double_t *vParams)
{
for (Int_t i=0;i<vNPars;i++) {
cout << "Params[" << i << "] = " << vParams[i] << endl;
}//for_i
}
//==================================================================
// macroTestClass.C
//==================================================================
//#ifndef ROOT_Varargs
#include "Varargs.h"
//#endif
void run()
{
// example of macro to test
gROOT->Reset();
gSystem->Load("/opt/rootcode/libTestClass.so");
TTestClass *test = new TTestClass("TestClass","C.Stratowa");
test->FInitTest(4,1.1,4.4,6.6,7.7);
delete test;
}//run
//==================================================================
// TestClass.h
//==================================================================
#ifndef __TestClass__
#define __TestClass__
#include "TNamed.h"
#include <iostream.h>
class TTestClass: public TNamed {
protected:
Int_t fNPar; //number of parameters
Double_t *fParams; //[fNPar] Array of fNPar parameters
public:
TTestClass();
TTestClass(const char *vName, const char *vTitle);
~TTestClass();
virtual void FInit(Int_t vNPar, Double_t *vParams);
virtual void FInitTest(Int_t vNPar,...);
ClassDef(TTestClass,1) //TestClass
};
#endif
//==================================================================
// TestClass.cxx
//==================================================================
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <iomanip.h>
//#ifndef ROOT_Varargs
#include "Varargs.h"
//#endif
#include "TestClass.h"
ClassImp(TTestClass);
TTestClass::TTestClass(): TNamed()
{
cout << "------TTestClass::TTestClass(default)------" << endl;
fNPar = 0;
fParams = 0;
}//Constructor
//----------------------------------------------------------------------//
TTestClass::TTestClass(const char *vName, const char *vTitle):
TNamed(vName,vTitle)
{
cout << "------TTestClass::TTestClass------" << endl;
fNPar = 0;
fParams = 0;
this->FInitTest(4,0.2,3.4,1.6,4.7);
}//Constructor
//----------------------------------------------------------------------//
TTestClass::~TTestClass()
{
cout << "------TTestClass::~TTestClass------" << endl;
if (fParams) {delete [] fParams; fParams = 0;}
}//Destructor
//----------------------------------------------------------------------//
void TTestClass::FInit(Int_t vNPar, Double_t *vParams)
{
cout << "------TTestClass::FInit------" << endl;
fNPar = vNPar;
Double_t *fParams = new Double_t[vNPar];
for (Int_t i=0;i<vNPar;i++) {
fParams[i] = vParams[i];
cout << "vParams[" << i << "] = " << vParams[i] << endl;
}//for_i
}//FInit
//----------------------------------------------------------------------//
void TTestClass::FInitTest(Int_t vNPar,...)
{
cout << "------TTestClass::FInitTest------" << endl;
Double_t *vParams = new Double_t[vNPar];
// get parameters
va_list vArgPtr;
va_start(vArgPtr,vNPar);
for (Int_t i=0;i<vNPar;i++) {
vParams[i] = va_arg(vArgPtr,Double_t);
}//for_i
va_end(vArgPtr);
this->FInit(vNPar,vParams);
delete [] vParams;
}//FInitTest
//==================================================================
// TestClassLinkDef.h
//==================================================================
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class TTestClass+;
#endif
//==================================================================
// MakeFile4TestClass
//==================================================================
# Makefile for class TestClass.
# shell: gmake -f Makefile4TestClass
ARCH = linuxppcegcs
CXX =
ObjSuf = o
SrcSuf = cxx
ExeSuf =
DllSuf = so
OutPutOpt = -o
ROOTCFLAGS := $(shell root-config --cflags)
ROOTLIBS := $(shell root-config --libs)
ROOTGLIBS := $(shell root-config --glibs)
ifeq ($(ARCH),linuxegcs)
# Linux with egcs (>= RedHat 5.2)
CXX = g++
CXXFLAGS = -O -Wall -fPIC
LD = g++
LDFLAGS = -O
SOFLAGS = -shared
endif
ifeq ($(ARCH),linuxppcegcs)
# MkLinux with egcs/glibc
CXX = g++
CXXFLAGS = -O -Wall -fPIC
LD = g++
LDFLAGS = -O
SOFLAGS = -shared -Wl,-soname,
endif
CXXFLAGS += $(ROOTCFLAGS)
LIBS = $(ROOTLIBS) $(SYSLIBS)
GLIBS = $(ROOTGLIBS) $(SYSLIBS)
#------------------------------------------------------------------------------
TESTCLASSO = TestClass.$(ObjSuf) TestClassDict.$(ObjSuf)
TESTCLASSS = TestClass.$(SrcSuf) TestClassDict.$(SrcSuf)
TESTCLASSSO = libTestClass.$(DllSuf)
OBJS = $(TESTCLASSO)
PROGRAMS = $(TESTCLASSSO)
#------------------------------------------------------------------------------
.SUFFIXES: .$(SrcSuf) .$(ObjSuf) .$(DllSuf)
all: $(PROGRAMS)
$(TESTCLASSSO): $(TESTCLASSO)
$(LD) $(SOFLAGS) $(LDFLAGS) $^ $(OutPutOpt) $@
clean:
@rm -f $(OBJS) core
.SUFFIXES: .$(SrcSuf)
###
TestClass.$(ObjSuf): TestClass.h
TestClassDict.$(SrcSuf): TestClass.h TestClassLinkDef.h
@echo "Generating dictionary TestClassDict..."
@rootcint -f TestClassDict.$(SrcSuf) -c TestClass.h TestClassLinkDef.h
.$(SrcSuf).$(ObjSuf):
$(CXX) $(CXXFLAGS) -c $<
This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:50:44 MET