i have a problem with global variables in a c++ shared library project. my library has to be working as a standard g++ shared library (.so) as well as a dll. i did this by creating files libiup_dll.cpp and libiup_dll.h, where i have something like
#ifdef BUILD_DLL
// code for the dll: wrapper functions around the classes in my shared library
#endif
in my dll, i need functions setloglevel(int) and geterrormsg(). in all my classes, i'd then append to a global variable errormsg all error messages. this variable should then be returned by the geterrormsg() function. i implemented this by using
std::string errormsg;
int loglevel;
in libiup_dll.h (outside and #ifdefs, so it should be globally available), and then putting
extern std::string errormsg;
extern int loglevel;
in my classes' .h files (outside the class, at the top of the files)
now i have two problems:
1) when compiling a command line program with g++, which uses my library, i get errors
Building target: libiup_test Invoking: GCC C++ Linker g++ -L"/home/hilboll/src/libiup/Release" -L/usr/local/lib -o"libiup_test" ./src/stratcalc/SimpleStratosphericColumnCalculatorTest.o ./src/interp/SimpleInterpolatorTest.o ./src/Test.o -lgsl -lhdf5 -lhdf5_cpp -lblas -liup /home/hilboll/src/libiup/Release/libiup.so: undefined reference to
loglevel' /home/hilboll/src/libiup/Release/libiup.so: undefined reference to
errormsg' collect2: ld returned 1 exit status make: *** [libiup_test] Error 1
even though in my command line program, there's no reference whatsoever to errormsg or loglevel.
2) when trying to compile the dll under windows with VS2008, i get
z:\src\vs\libiup_dll\libiup_dll.h(229) : error C2086: 'std::string errormsg': Neudefinition z:\src\libiup\src\stratcalc../interp/SimpleInterpolator.h(16): Siehe Deklaration von 'errormsg' z:\src\vs\libiup_dll\libiup_dll.h(234) : error C2086: 'int loglevel': Neudefinition z:\src\libiup\src\stratcalc../interp/SimpleInterpolator.h(17): Siehe Deklaration von 'loglevel'
as far as i understand, it means that VS thinks i'm defining the two variables twice. however, in SimpleInterpolator.h 16/17, there's the extern declarations only ...
it seems i somehow haven't understood how global variables work, yet. any help is greatly appreciated!
The trick is to know that each .cpp file is a compilation unit - ie the things that get compiled. Each one is a total individual and know nothing about each other. Its only at the link stage that these are brought together.
Now, extern says "this variable can be found elsewhere" to the compiled cpp file, the compiler just places a reference hint to the linker to sort things out.
So, as you've put the variable definitions in a header file, chances are you're including that header into 2 (or more) cpp files. So each of those cpp files, when compiled, think they have the real variable. The linker then comes along and sees too many.
Place the variables into a cpp file of their own (or into the main cpp file), and only put extern references in header files. You should be ok with multiply-defined symbols then.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With