Compiling a function using TObject fails


I want to use a class, which I created and which is a TObject, in a macro:

int test() {

TField *tf = new TField(101.);

return 1;


I want to compile this macro (".x test.C+"). Just running the macro without the “+” works
fine. I also tried compiling the Class and loading it with gSystem->Load(“TField.C++”). It is
the same: I can run the macro in root without problems, but I can not compile it using “+”.
If I leave away the ClassImp and ClassDef statements, all works fine. But then it will
not be an TObject any more, which means, I will not be able to use it in a collection.

The files are attached.

root [0] .x test.C
Info in TUnixSystem::ACLiC: creating shared library /misc/lippmann/rpc/rate/test/./

root [2] .x test.C+
Info in : script has already been loaded in interpreted mode
Info in : unloading /misc/lippmann/rpc/rate/test/./test.C and compiling it
Info in TUnixSystem::ACLiC: creating shared library /misc/lippmann/rpc/rate/test/./
dlopen error: /misc/lippmann/rpc/rate/test/./ undefined symbol: _ZN6TField11ShowMembersER16TMemberInspectorPc
Load Error: Failed to load Dynamic link library /misc/lippmann/rpc/rate/test/./
/usr/lib/crt1.o(.text+0x18): In function _start': : undefined reference tomain’
/misc/lippmann/rpc/rate/test/./fileWmuOfv.o(.text+0x807): In function __static_initialization_and_destruction_0(int, int)': : undefined reference toROOT::GenerateInitInstance(TField const*)’
/misc/lippmann/rpc/rate/test/./fileWmuOfv.o(.gnu.linkonce.d._ZTV6TField+0xe4): undefined reference to TField::ShowMembers(TMemberInspector&, char*)' /misc/lippmann/rpc/rate/test/./fileWmuOfv.o(.gnu.linkonce.d._ZTV6TField+0xe8): undefined reference toTField::Streamer(TBuffer&)’
/misc/lippmann/rpc/rate/test/./fileWmuOfv.o(.gnu.linkonce.t._ZNK6TField3IsAEv+0x13): In function TField::IsA() const': : undefined reference toTField::Class()’
collect2: ld returned 1 exit status
!!!Dictionary position not recovered because G__unloadfile() is used in a macro!!!
*** Interpreter error recovered ***

The trouble seems to be here:

c++filt _ZN6TField11ShowMembersER16TMemberInspectorPc
TField::ShowMembers(TMemberInspector&, char*)

Any idea?


  Christian Lippmann

test.tar (10 KB)

the problem is that you are trying to compile test.C, which uses TField (and which needs the dictionary methods for TField). But you will generate the dictionary only when running test() - i.e. for that it needs to be compiled. More clearly: to compile test it needs to be run. That won’t work. Instead, you could slpit your code like this:

testOuter.C:int testOuter() { gROOT->LoadMacro("TField.C++"); gROOT->ProcessLine(".x testInner.C+"); return 0; }
testInner.C:int testInner() { TField *tf = new TField(101.); tf->PrintMe(); return 1; }

Note how testOuter does not rely on TField, only testInner - but that gets compiled in a “sub-interpreter” after TField’s dictionary has been created by LoadMacro(“TFile.C++”).

Cheers, Axel.

Thank you very much! It works.