0

I have an issue. I have a class structure that looks somewhat like this:

// Common.hpp

template <typename Type>
class CommonInternalRegistrar
{
    CommonInternalRegistrar ( Type* pointerToRegister ) ;
} ;
template <typename Type>
class DerivesFrom
:   public virtual Type
,   public CommonInternalRegistrar<Type>
{
    DerivesFrom ()
    :   CommonInternalRegistrar<Type> ( this )
    { }
} ;

class MyInterface
{
    virtual void doSomething () =0 ;
} ;


// CommonClass1.hpp

class DLL_FLAG MyCommonClass
:   public DerivesFrom<MyInterface>
{ } ;


// Class1.cpp in LibraryA.dll

namespace some_namespace {
    class DLL_FLAG_A MyClass
    :   public MyCommonClass
    { } ;
}


// Class2.cpp in LibraryB.dll

namespace some_namespace {
    class DLL_FLAG_B MyClass
    :   public DerivesFrom<MyInterface>
    { }
}

Some notes for those pedantic people out there:

  • I'm being lax with public: in the classes for this example for readability

  • In this example, it's not immediately obvious that DerivesFrom does anything useful. However, in our architecture, it does, and you'll have to trust that it's necessary.

  • DLL_FLAG is a macro which, when the code is being compiled

Now, the problem:

In LibraryA, MyClass and MyCommonClass are exported. Because MyCommonClass is exported, DerivesFrom is also exported (at least it appears so in VS2012).

Then, when LibraryB exports MyClass, it also exports DerivesFrom (wtf?).

Then, when we link MyExecutable.exe (as part of the build process defined by cmake) against LibraryA.dll and LibraryB.dll, it fails because there is a duplicate DerivesFrom - one from each library.

Solutions we've seen before and can't use:

__declspec(dllexport) DerivesFrom in one library and import in the other. However, this requires too much crap in the code which really shouldn't be there. It then forces one library to "host" the class, but that concept isn't meaningful in our system.

"Don't do that." Well, I say Visual Studio shouldn't do that. Or we should be able to specify that DerivesFrom (and all instantiations of DerivesFrom) shall have internal linkage only so its symbol is never exported.

I'm at a loss for:

  • Why VS2012 is auto-exporting the templates and refusing to let each library use their own.

  • Why I can't tell it to never export those templates (which might not be feasible since, sometimes, two libraries might derive from a class which has a DerivesFrom<> in it).

  • How to get around this issue.

Any ideas would be greatly appreciated!

iAdjunct
  • 2,739
  • 1
  • 18
  • 27
  • Did you *really* give two libraries the exact same namespace or was that just an obfuscation oops? – Hans Passant Dec 10 '14 at 15:50
  • Obfuscation oops. Really they're mostly anonymous namespaces in the libraries and are therefore not exported, but it doesn't particularly matter for this issue (since not all are). – iAdjunct Dec 10 '14 at 16:10

0 Answers0