1

I'm attempting to build a static library, containing definitions of DDS topics obtained from various IDL files. I'm using OpenDDS as my middleware.

When I create an IDL file containing a sequence<long>, compile it into my static library, and then link the static library against my application, I get linker errors involving multiple definition of symbols:

Error   LNK2005 "public: void __cdecl TAO::unbounded_value_sequence<int>::length(unsigned int)" (?length@?$unbounded_value_sequence@H@TAO@@QEAAXI@Z) already defined in TAO.lib(TAO.dll)    

I believe this is because my static library contains a template instantiation of unbounded_value_sequence, and my application also contains an instantiation. It seems to be coming from within ACE TAO, which is used by OpenDDS.

I'm looking for a way to avoid instantiating the template in my static library altogether, so that it can just use the definition within the application when they are linked together. I tried adding the following:

extern template class TAO::unbounded_value_sequence<int>;

This produced the following error:

Error   C2961   'TAO::unbounded_value_sequence<CORBA::Long>': inconsistent explicit instantiations, a previous explicit instantiation did not specify '__declspec(dllimport)'

I've tried to locate that instantiation, but its not in my code. It may be within ACE itself.

The problem does not occur if I build everything in the one project, but that is not an ideal solution.

endorph
  • 193
  • 10

1 Answers1

1

What you have to do to use extern templates is a bit different. Indeed, declaring the extern template will prevent it's instanciation. But you will need an instanciation somewhere. That somewhere is usually in a cpp with the name of the template you want to compile.

unbounded_value_sequence.h:

// template struct here

extern template class TAO::unbounded_value_sequence<int>;
extern template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library

unbounded_value_sequence.cpp:

#include "unbounded_value_sequence.h"

// Here you compile them one time.
template class TAO::unbounded_value_sequence<int>;
template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library

That will make your template to be instantiated one time only, inside your library. The compiler will generate a unbounded_value_sequence object file that contains your template instantiations. They will exist only there.

Don't forget that you still need to make your template implementation visible in the header if you want users of your library use your template class with theirs.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141