How to generate a class dictionary

Hi,

I would like to create a TTree with a vector of a home-made structure as a branch. I have understood that it is not possible to do this unless making the struct become a class and generate a dictionary for this class (or even for vector). However, I am sorry to say that the documentation is quite obscure to my mind. All I can find on this subject are sibylline answers like “you need to generate the dictionary” or “you need a #pragma link”, or “have a look at the User Guide’s ‘Adding a Class’ chapter”, which I am unfortunately unable to profit by…

So let’s try with a very simple example :

[code]// myclass.h
#ifndef MyClass
#define MyClass

#include <Rtypes.h>

using namespace std;

class myclass
{
public:
myclass() { a=0; b=0; };
~myclass() {};
int a;
int b;
ClassDef(myclass,1)
};

#endif[/code]

[code]// myclass.cxx
#include “myclass.h”

ClassImp(myclass)[/code]

[code]// myprog.C

// If I well understood, this should be equivalent to put it here or in LinkDef.h, am I right ?
// Anyway it does not seem to affect the result…
#ifdef CINT
#pragma link C++ class myclass+;
#endif

#include “myclass.h”
#include “TTree.h”

using namespace std;

int main(){
myclass zeClass;
TTree
zeTree=new TTree(“zeTree”,“zeTree”);
zeTree->Branch(“zeClass”,“myclass”, &zeClass);

return 0;
}[/code]

I then type “rootcint eventdict.cxx -c myclass.h”. Including eventdict.h in myprog.C and adding it as a dependency into the Makefile do not seem to change anything, neither does removing the second argument of the “Branch” call. This lead me in any case to the following compilation error :

Commenting either the Branch or the ClassDef calls make the compilation working — however in the latter case the execution fails (obviously ?) on “Error in TTree::Bronch: Cannot find class:myclass”.

So could anybody please tell me what I am missing ?

Thanks.

[quote]// If I well understood, this should be equivalent to put it here or in LinkDef.h, am I right ?
// Anyway it does not seem to affect the result…[/quote]
True, if and only if you are compiling your code via ACliC.

[quote]or “have a look at the User Guide’s ‘Adding a Class’ chapter”[/quote]Did you get a change to read this chapter? See root.cern.ch/root/doc/RootDoc.html.

[quote]I then type “rootcint eventdict.cxx -c myclass.h”. Including eventdict.h in myprog.C and adding it as a dependency into the Makefile do not seem to change anything[/quote]Do no add the eventdict.h in myprog.C, instead you need to compile eventdict.cxx (the same way you compile myprog.C) and include the .o file in your library and/or executable.

Philippe

1 Like

Thanks for the quick reply.

[quote=“pcanal”][quote]// If I well understood, this should be equivalent to put it here or in LinkDef.h, am I right ?
// Anyway it does not seem to affect the result…[/quote]
True, if and only if you are compiling your code via ACliC.[/quote]Ok. If using ACliC is just using the interpretor, then I don’t compile via ACliC, so I need a LinkDef.h (or is it myclassLinkDef.h ???).

[quote=“pcanal”][quote]or “have a look at the User Guide’s ‘Adding a Class’ chapter”[/quote]Did you get a change to read this chapter? See root.cern.ch/root/doc/RootDoc.html.[/quote]Yes, that is the point. I feel this chapter quite confusing — sorry for that…

[quote=“pcanal”]Do no add the eventdict.h in myprog.C, instead you need to compile eventdict.cxx (the same way you compile myprog.C) and include the .o file in your library and/or executable.[/quote]Unfortunatly I still have the problem… Running on a computer with a more recent ROOT version, the message is more explicit for a lambda user like me, but it does not help very much :

.o/Essai.o: dans la fonction « Branch<myclass> »: /opt/root/include/root/TTree.h:213: référence indéfinie vers « typeinfo for myclass»

[quote]Ok. If using ACliC is just using the interpretor[/quote]Not quite. It is compiling a shared library via a simple ROOT command (or on the command line). For example if you have:[code]// myscript.C
#ifndef MyScript_H
#define MyScript_H
// This part could be in a separate file name myscript.h
#include <Rtypes.h>
using namespace std;
class myclass
{
public:
myclass() { a=0; b=0; };
virtual ~myclass() {};
int a;
int b;
ClassDef(myclass,1);
};
#endif

// #include "myscript.h"
ClassImp(myclass);
#include “TTree.h”

using namespace std;

int myscript()
{
myclass zeClass = new myclass;
TTree
zeTree=new TTree(“zeTree”,“zeTree”);
zeTree->Branch(“zeClass”,“myclass”, &zeClass);
return 0;
}[/code]
I can compile, load and run your code (sucessfully) by just doing (on the ROOT prompt):root [] .x myscript.C+
This avoid any makefile writing or any linkdef or (direct) call to rootcint.

[quote]opt/root/include/root/TTree.h:213: référence indéfinie vers « typeinfo for myclass»[/quote]This means that not ALL the virtual function of myclass have been loaded into your executable.
This usually means that you have not properly linked against the compiled dictionary.

[quote]then I don’t compile via ACliC, so I need a LinkDef.h (or is it myclassLinkDef.h ???). [/quote]Well, not necessarily:

Cheers,
Philippe

[quote=“pcanal”]I can compile, load and run your code (sucessfully) by just doing (on the ROOT prompt):root [] .x myscript.C+[/quote]Ok, I see now.

[quote=“pcanal”]This avoid any makefile writing[/quote]Might be a good idea, since my error was effectively in the Makefile… Sorry for that. :blush:

It works fine now (well, with the “=new myclass” that I forgot, in addition…), thank you very much.

[quote]rootcint -f eventdict.cxx -c myclass.hwill generate the dictionary for a class named after the name of the last argument (aka in your example a class named myclass. You can also write a linkdef file (either names would work) and use:rootcint -f eventdict.cxx -c myclass.h myclassLinkDef.h[/quote]Ok. I would just ensure to understand well : the first case is sufficient, and the second case allow more flexible manipulations on the dictionary generation, am I right ?

1 Like

[quote] the first case is sufficient, and the second case allow more flexible manipulations on the dictionary generation, am I right ?[/quote]Yes.