1

I am trying to create a dynamic library from various .cpp files sharing the same .h. It's something like this:

// mylib1.cpp
namespace mylib {
    namespace part1 {
        void init() {
            part1::commonvar = true;
        }
    }
}

and

// mylib2.cpp
namespace mylib {
    namespace part2 {
        void check() {
            if (part1::commonvar == true) {
                // do something
            }
        }
    }
}

and this is the common header

// mylib.h
#ifdef __cplusplus 
extern "C" {
#endif
    namespace mylib {
        namespace part1 {
            bool commonvar = false;
            void init();
        }
        namespace part2 {
            void check();
        }
    }
#ifdef __cplusplus 
}
#endif

I am using GCC (MingW) to compile and link this into a single DLL like this:

g++ -Wall -s -O2 -c mylib1.cpp -o mylib1.o
g++ -Wall -s -O2 -c mylib2.cpp -o mylib2.o
g++ -Wall -s -O2 -shared -o MyLib.dll -Wl,--out-implib=lib/libMyLib.dll.a mylib1.o mylib2.o

So, my problem is that when I do all this I get multiple definition error for that variable, when trying to link those two objects. So, I wonder if there's a workaround to make commonvar be common for both namespaces, but not duplicated in both object files. I can make it a member of the namespace "mylib", if necessary, and I can use pre-processor commands, too.

Thanks for your help

ali
  • 10,927
  • 20
  • 89
  • 138

2 Answers2

2

Non-const global variables have external linkage. You are importing the same definition of the commonvar global variables into several translation units, and the linker will eventually complain that you defined that symbol more than once, violating the One Definition Rule.

You should use the extern keyword to turn the definition of your global variable into a declaration, and define the global variable in just one .cpp file:

MyLib.h

namespace mylib {
    namespace part1 {
        extern bool commonvar;
    //  ^^^^^^
        void init();
    }
    namespace part2 {
        void check();
    }
}

MyLib.cpp (or any other .cpp file, as long as it is only one)

namespace mylib {
    namespace part1 {
        bool commonvar;
    }
}

If you are wondering why your include guards (in case you are using them) are not preventing multiple definitions of the same symbol in different translation units, see this

Community
  • 1
  • 1
Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
  • I will try this. I understand what is going on under the hood, I just didn't know how to make it be understood as an exter/exported element. – ali Feb 27 '13 at 14:54
  • Works like charm. Initialization of that variable can be made in the cpp or the header? Thanks – ali Feb 27 '13 at 14:57
  • @ali: In the `.cpp`. What you have in the header is just a *declaration*. – Andy Prowl Feb 27 '13 at 14:59
0

How about the following

  bool* init(){
      static bool commonvar = false;
      return &commonvar;     
  }
Adnan Akbar
  • 718
  • 6
  • 16
  • ...as a last solution I will create a function to return that – ali Feb 27 '13 at 14:53
  • 1
    because compiler compiles each source file seperately will have the same symbol in multiple object files , finally linking will generate linker error. extern keyword can be used to avoid that. – Adnan Akbar Feb 27 '13 at 14:58