Loading external libraries into CINT

Hi all,

I would like to use an external (shared) library and its classes inside CINT. I tried gSystem->Load("mylib")which seems to work. Nevertheless I am not able to use the classes that are defined inside the library. Since I am just a “stupid C++ coder” I am not very familiar with things like symbols, #pragma statements or dictionaries (But in fact I think it has something to do with that :slight_smile:). In the root docs I found#ifdef __MAKECINT__ #pragma link C++ class MyClass #endifBut if I understand it right this works only for compiling the library with ACLiC. My library is compiled externally and I would like to leave it like that. Can someone give me a hint how to do that? Perhaps I should mention that I am using namespaces in my library so all classes are defined in namespaces. Does that make any trouble?

Thanks in advance, Mathias

Hi,

let’s walk through an example - it should be straightforward to apply this to your case. Suppose I want to generate the dictionary for SAX2, part of libxml2. I’d create a file sax2Linkdef.h:[code]#ifdef CINT
#pragma link C++ defined_in /usr/include/libxml2/libxml/HTMLparser.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/HTMLtree.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/SAX2.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlIO.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlautomata.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlerror.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlexports.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlmemory.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlmodule.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlreader.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlregexp.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlsave.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlschemas.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlschemastypes.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlstring.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlunicode.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlversion.h;
#pragma link C++ defined_in /usr/include/libxml2/libxml/xmlwriter.h;

#pragma link C++ all;
#pragma link C++ all_function;
#pragma link C++ all_datamember;

#endif
[/code]Then I’d run rootcint -f dictSAX2.cxx -c -I/usr/include/libxml2 -p /usr/include/libxml2/libxml/*.h sax2Linkdef.h g++ -I /usr/include/libxml2 `root-config --cflags` -c dictSAX2.cxx g++ -shared -o libSAX2Dict.so dictSAX2.o i.e. I would create the dictionary, compile it, and build a shared library from it.

Now I can start root, and run gSystem->Load("/usr/bin/libxml2") gSystem->Load("libSAX2Dict") xmlTextReaderPtr reader = xmlNewTextReaderFilename("index.html")
I’ll set up a web page describing this procedure, at some point…

Cheers, Axel.

Hi Axel,

Thanks for the very clear description. Nevertheless I get a bunch ofclass,struct,union or type *MyClass* not defined and similar messages for some of my classes when running rootcint. I can only guess that this is because of the mentioned namespaces where my classes are defined in (without the namespaces the classnames would not be unique). Do you agree and is there a workaround for this?

Cheers, Mathias

Hi,

can you post / send me a header for which you see this error message? I don’t see how this could be caused by classes in a namespace. It’s either due to invalid C++, or due to a bug or known limitation in (root)cint. What root version do you use?

Axel.

Hi,

Attached are the requested headers. The linkdef is:[code]#ifdef CINT
#pragma link C++ defined_in /home/mathias/ana/kgana/lib/commondefs.h;
#pragma link C++ defined_in /home/mathias/ana/kgana/lib/kchar.h;
#pragma link C++ defined_in /home/mathias/ana/kgana/lib/kstring.h;

#pragma link C++ all;
#pragma link C++ all_function;
#pragma link C++ all_datamember;

#endif[/code]The command line i used isrootcint -f dictkgana.cxx -c /home/mathias/ana/kgana/lib/kstring.h /home/mathias/ana/kgana/lib/char.h /home/mathias/ana/kgana/lib/commondefs.h kganaLinkdef.hand the error messageError: class,struct,union or type KString not defined prec_stl/memory:30: Error: class,struct,union or type KString not defined prec_stl/memory:31: Error: class,struct,union or type KString not defined prec_stl/memory:36: Error: class,struct,union or type KString not defined prec_stl/memory:37: Error: class,struct,union or type KString not defined prec_stl/memory:38: Error: class,struct,union or type KString not defined prec_stl/vector:44: Error: left not allocated(1), maybe duplicate declaration /home/mathias/ana/kgana/lib/kstring.h:45: Error: right not allocated(1), maybe duplicate declaration /home/mathias/ana/kgana/lib/kstring.h:46: Error: mid not allocated(1), maybe duplicate declaration /home/mathias/ana/kgana/lib/kstring.h:47: Error: range not allocated(1), maybe duplicate declaration /home/mathias/ana/kgana/lib/kstring.h:48: Error: class,struct,union or type uint KString not defined /home/mathias/ana/kgana/lib/kstring.h:175: Error: class,struct,union or type uint KString not defined /home/mathias/ana/kgana/lib/kstring.h:185: Syntax error /home/mathias/ana/kgana/lib/kstring.h:217: Syntax error /home/mathias/ana/kgana/lib/kstring.h:228: Syntax error /home/mathias/ana/kgana/lib/kstring.h:241: Syntax error /home/mathias/ana/kgana/lib/kstring.h:254: Error: class,struct,union or type signedlongint KString not defined /home/mathias/ana/kgana/lib/kstring.h:402: Error: cannot open file "/home/mathias/ana/kgana/lib/char.h" :0: !!!Removing dictkgana.cxx dictkgana.h !!! Error: rootcint: error loading headers...Root version is 5.08/00

Thx a lot!!!

Mathias
commondefs.h (2.01 KB)
kchar.h (2.16 KB)
kstring.h (13.7 KB)

Hi,

2 simples issues.
uint is not defined, so add at least something like:

#ifdef __MAKECINT__ typedef unsigned int uint; #endif

Your code makes use of CPP macros that is beyond the current ability of the CPP preprocessor integrated in CINT. Instead use the compiler’s CPP preprocessor by using the -p option:

rootcint -f dictkgana.cxx -c -p /home/mathias/ana/kgana/lib/kstring.h /home/mathias/ana/kgana/lib/char.h /home/mathias/ana/kgana/lib/commondefs.h kganaLinkdef.h
Cheers,
Philippe

Hi Philippe,

Thanks for your response that indeed helped to at least reduce the list of errors. Concerning the undefined uint type I thought it would be sufficient to have included the commondefs.h where the uint is defined. Nevertheless by replacing all uint with unsigned int the corresponding errors are gone. Also your second advice helped to get rid of some error messages. But now I have a new one. When using your command line I getIn file included from /tmp/8tRwwA_cint.cxx:1: /tmp/fileCQUDXb_rootcint.h:4:46: error: /home/mathias/ana/kgana/lib/char.h: Datei oder Verzeichnis nicht gefunden Error: external preprocessing failed. :0: !!!Removing dictkgana.cxx dictkgana.h !!! Error: rootcint: error loading headers...The german means “File or Directory not found”. I also had a try withrootcint -f dictkgana.cxx -c -I/home/mathias/ana/kgana/lib -p /home/mathias/ana/kgana/lib/kstring.h /home/mathias/ana/kgana/lib/char.h /home/mathias/ana/kgana/lib/commondefs.h kganaLinkdef.hwith the same result. Now why are the headers not found?

Cheers, Mathias

Hi,
isn’t it called kchar.h?
Axel.

Ooops, sure, you’re right. I should think about bying my girlfriend one of those “I’m with stupid” T-Shirts :blush:

Thanks a lot for getting this working!!!

Cheers, Mathias

So in principal I can get it working now. Just one minor comment. When doingg++ -I/home/mathias/ana/kgana/lib `root-config --cflags` -c dictkgana.cxxI getdictkgana.cxx: In function ‘int G__dictkgana_193_8_2(G__value*, const char*, G__param*, int)’: dictkgana.cxx:735: error: ‘KString’ was not declared in this scope dictkgana.cxx:735: error: template argument 1 is invalid dictkgana.cxx:735: error: template argument 2 is invalid dictkgana.cxx:735: error: invalid type in declaration before ‘,’ token dictkgana.cxx:735: error: cannot convert ‘std::vector<kg::KString, std::allocator<kg> >’ to ‘const int’ in initialization dictkgana.cxx:736: error: ‘KString’ cannot appear in a constant-expression dictkgana.cxx:736: error: template argument 1 is invalid dictkgana.cxx:736: error: template argument 2 is invalidThe corresponding lines in dictkgana.cxx areconst vector<KString> *pobj,xobj=((const kg::KString*)(G__getstructoffset()))->split(*(kg::KString*)libp->para[0].ref); pobj=new vector<KString>(xobj);So obviously there is a lack of the kg:: namespace for KString. When fixing this by hand everything works fine and I am able to load my lib into root. Don’t know if I’m still doing something wrong cause everywhere else in dictkgana.cxx KString always comes with kg::

Cheers, Mathias

Hi,

rootcint fails to do to the lookup properly. It sees KString::split returning a StringList, and it finds StringList to be #defined as std::vector (in kstring.h). Changing that to #define StringList std::vector<::kg::KString> should fix this problem.

We’re re-writing the lookup; this will get fixed on the way.

Axel.

Hi Axel,

When using#define StringList std::vector<kg>I got some error messages concerning the two colons in front of the kg. When leaving them out everything is fine. So now I’m happy, thanks again for the discussion.

Cheers, Mathias

Edit: Funny, even the forum-interpreter seems to have problems with double-colons. I meant#define StringList std::vector<::kg::KString>of course.

How do i achieved simliar logic with cling since CINT is deprecated. Also i am using cling only and not root.