Problem with compiled function library

Hello,

I’m trying to create a library with functions and classes, some of which use ROOT classes, but are not derived from ROOT classes. I would like to compile these classes and functions prior to using ROOT to make passing them to other users a little easier.

I’ve created a simple example which has a function called foo which simply prints “Hello World” to stdout.

{
    gSystem->Load("libFoo.so");
    
    foo();
}

The above seems to load the library, but when I run the code it does not print “Hello World” to stdout. To get this far I had to create a libFoo.rootmap file to let it know libFoo contained a function called foo, though I am not sure I got the rootmap syntax correct.

To run the code I use

root -c foo_test.C -q

If I remove the .rootmap file I get an error that says foo is declared, but is not defined.

Also, I’m not sure if I need to create dictionary files for classes which are not derived from ROOT classes. At any rate the behavior seems to be the same if I do not create and use the dictionary files.

I’ve attached the small example.

Any help is appreciated.

Best regards,
Terry
test.tar.gz (750 Bytes)

VIVE L’AMOUR!
in your “fooLinkDef.h” file, change:

into:

See also:
http://root.cern.ch/root/RootCintMan.html
http://root.cern.ch/drupal/content/selecting-dictionary-entries-linkdefh
http://root.cern.ch/drupal/content/interacting-shared-libraries-rootcint
http://root.cern.ch/drupal/content/adding-your-class-root-classdef

BTW. The “clean” target in your “makefile” should also remove “foo_dict.h”, not only “foo_dict.C”.

I am stupid. No?
Pepe Le Pew.

It works!

I knew there was something very basic I was missing.

Thank you very much.

Terry

Hello,
I was struggling with almost exactly the same problem and I found this thread on the topic. However, once I tried adding the line:

#pragma link C++ function foo;
The problem didn’t get solved.
I quickly realised that my testing script is not unnamed like the one in the example provided by “terrydoherty”,
and this seems to be the difference. Normally, I like to compile my scripts just like they were normal C++ programs. So, I created a testing named script, pretty much similar to the one in the example, called foo_test2.C :

#include <TSystem.h> #include "foo.h" void foo_test2() { gSystem->Load("libFoo.so"); foo(); }
The piece of code compiles with no problems, but as soon as I try to execute it with root:

root -q foo_test2.C root [0] Processing foo_test2.C... Error: foo() declared but not defined foo_test2.C:8: *** Interpreter error recovered ***
I get the error again.
This doesn’t happen with the unnamed script foo_test.C:

root -q foo_test.C root [0] Processing foo_test.C... Hello World
And now the disturbing part:
If I comment the line number 2 in foo_test2.C, and I leave the code like this:

#include <TSystem.h> // #include "foo.h" void foo_test2() { gSystem->Load("libFoo.so"); foo(); }
The program works perfectly:

root -q foo_test2.C root [0] Processing foo_test2.C... Hello World
But the macro doesn’t compile since the compiler doesn’t know the definition of the function foo().
Don’t you find this strange? This is actually a problem for me because I don’t know how to compile my macros (to make them work faster in a precompiled program) and make them work with CINT at the same time.
Any help is appreciated. I have modified the original example by Terry Doherty to include the not working cases.
test.2.tar.gz (4.12 KB)
Best regards,
Alberto

Hi,

[quote]But the macro doesn’t compile since the compiler doesn’t know the definition of the function foo().
Don’t you find this strange? [/quote]This is somewhat the expected behavior.

The fact that the interpreter is confused by the presence of the #include “foo.h” is somewhat unexpected (it is a bug), however you can easily work around it with:#include <TSystem.h> #ifndef __CINT__ #include "foo.h" #endif void foo_test2() { gSystem->Load("libFoo.so"); foo(); }

However compile this code does not make a lot of sense unless you also update it as:#include <TSystem.h> #ifndef __CINT__ #include "foo.h" #endif void foo_test2() { #ifdef __CINT__ gSystem->Load("libFoo.so"); #endif foo(); }as the original code might compile properly but will not link and/or load properly unless you explicitly load libFoo before loading the compiled version of test2 (the loading of the library will failed to the missing symbol for foo).

Cheers,
Philippe.

Thanks, Philippe!
I forgot the #ifdef / #ifndef CINT trick.
That’s enough to make the macros compatible in both CINT and precompiled modes.