0

我有一个问题。我有一个看起来有点像这样的类结构:

// 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>
    { }
}

给那些迂腐的人的一些注意事项:

  • 我对公众很松懈:在这个例子的类中为了可读性

  • 在这个例子中,DerivesFrom 做任何有用的事情并不是很明显。但是,在我们的架构中,确实如此,您必须相信它是必要的。

  • DLL_FLAG 是一个宏,在编译代码时

现在,问题:

在 LibraryA 中,导出了 MyClass 和 MyCommonClass。因为导出了 MyCommonClass,所以也导出了 DerivesFrom(至少在 VS2012 中是这样)。

然后,当 LibraryB 导出 MyClass 时,它也会导出 DerivesFrom (wtf?)。

然后,当我们将 MyExecutable.exe(作为 cmake 定义的构建过程的一部分)链接到 LibraryA.dll 和 LibraryB.dll 时,它会失败,因为有一个重复的 DerivesFrom - 每个库都有一个。

我们以前见过但不能使用的解决方案:

__declspec(dllexport) DerivesFrom 在一个库中并在另一个库中导入。但是,这需要在代码中添加太多实际上不应该存在的废话。然后它强制一个库“托管”该类,但这个概念在我们的系统中没有意义。

“不要那样做。” 好吧,我说 Visual Studio 不应该那样做。或者我们应该能够指定 DerivesFrom(以及 DerivesFrom 的所有实例化)仅应具有内部链接,因此它的符号永远不会被导出。

我不知所措:

  • 为什么 VS2012 会自动导出模板并拒绝让每个库使用自己的。

  • 为什么我不能告诉它永远不要导出这些模板(这可能不可行,因为有时,两个库可能派生自一个包含 DerivesFrom<> 的类)。

  • 如何解决这个问题。

任何想法将不胜感激!

4

0 回答 0