How to access variables from a library?

Hi there!
I’m currently trying to somehow plug a bunch of C libraries into ROOT. What this means is:

  • I got the libraries, which work fine when included into a C project
  • I am trying to write a ROOT macro to combine my libraries with ROOT’s graphing… abilities.

Turns out it’s hard to access the variables, which are global in one of my library files and declared extern in a header. So my minimal example is:
The 1st library ./src/library.c[code]#include <library.h>

int a, b;

void print_numbers(void)
{
a=5;
b=7;
printf(“a=%d\n”,a);
printf(“b=%d\n”,b);
}[/code]with corresponding header ./include/library.h:[code]#ifndef _LIBRARY_H
#define _LIBRARY_H

void print_numbers(void);

extern int a;
extern int b;

#endif[/code]
The 2nd library ./src/library2.c[code]#include <library2.h>
#include <library.h>

void print_numbers_from_lib1(void)
{
a=13;
b=42;
printf(“a=%d\n”,a);
printf(“b=%d\n”,b);
}[/code]with corresponding headervoid print_numbers_from_lib1(void);. The two of these libraries get called from the root macro macro.cmacro() { gROOT->ProcessLine(".include ./include"); gROOT->ProcessLine(".L ./src/library.c++"); gROOT->ProcessLine(".L ./src/library2.c++"); print_numbers(); print_numbers_from_lib1(); cout << 2*a << endl; }
Calling “root -l macro.c” gives an error[quote]a=5
b=7
a=13
b=42
Error: Symbol a is not defined in current scope macro.c:9:[/quote]. Now the funny bit is: if I remove the extern declarations, ROOT can access the variable (but library2 can’t), as is proven by an easier macro[code]macro()
{

cout << “Hello world” << endl;
gROOT->ProcessLine(".include ./include");
gROOT->ProcessLine(".L ./src/library.c++");
print_numbers();
cout << 2*a << endl;
}[/code]which yields the expected[quote]a=5
b=7
10[/quote]. But this isn’t an option, since in this case the second library can’t access the variables anymore (obviously, since the "extern"s are missing):[quote]Hello world
Info in TUnixSystem::ACLiC: creating shared library <…>/access_library_variables/././src/library_c.so
Info in TUnixSystem::ACLiC: creating shared library <…>/access_library_variables/././src/library2_c.so
In file included from <…>/access_library_variables/././src/fileXcAm6k.h:32,
from <…>/access_library_variables/././src/fileXcAm6k.cxx:16:
<…>/access_library_variables/././src/library2.c: In function ‘void print_numbers_from_lib1()’:
<…>/access_library_variables/././src/library2.c:6: error: ‘a’ was not declared in this scope
<…>/access_library_variables/././src/library2.c:7: error: ‘b’ was not declared in this scope
g++: <…>/access_library_variables/././src/fileXcAm6k.o: No such file or directory
Error in : Compilation failed![/quote]
So is there any possibility to have these variables accessible by ROOT and C at the same time? I’m pretty sure I’m missing something completely obvious, so please don’t hesitate to suggest the most basic mistakes.

Best wishes,
Rufus

Hi Rufus,

In The 1st library ./src/library.c use #ifndef __CINT__ #include <library.h> #endif ....Cheers,
Philippe.

Amazing, this works, thank you! Could you please explain a bit (or post a link)? Especially I’m puzzled why I don’t need to keep my 2nd library from loading its header.

Now moving on from the minimal example towards my real use case, I get into trouble with the defines in my library. Given the new header file include/library.h[code]#ifndef _LIBRARY_H
#define _LIBRARY_H

void print_numbers(void);

extern int a;
extern int b;

#define HALLO 5

#endif[/code]the define is not known to ROOT: “cout << HALLO << endl” yields[quote]Error: Symbol HALLO is not defined in current scope macro.c:6:[/quote]. I can make it known to ROOT by including library.h in macro.c, but this breaks my function definitions: macro.c like[code]#include <include/library.h>

macro()
{
cout << “Hello world” << endl;
cout << “HALLO: " << HALLO << endl;
gROOT->ProcessLine(”.include ./include");
gROOT->ProcessLine(".L ./src/library.c++");
gROOT->ProcessLine(".L ./src/library2.c++");
print_numbers();
print_numbers_from_lib1();
cout << 2*a << endl;

}[/code]gives[quote]HALLO: 5
(…)
Error: print_numbers() header declared but not defined macro.c:10:[/quote]So is there a way to work with defines and variables short of separating them in the source code (i.e. stuffing them in separate files variables.h and defines.h)?

[quote] Could you please explain a bit (or post a link)?
[/quote]You observerd that [quote]Now the funny bit is: if I remove the extern declarations, ROOT can access the variable (but library2 can’t)[/quote]so this means that the extern were hindering the proper generation of the dictionary. By using the #ifndef CINT they are not seen by the dictionary generator but they are still seen by the compiler.

Cheers,
Philippe.