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

そこにいるそれらの衒学的な人々のためのいくつかのメモ:

  • 私は読みやすくするためにこの例のクラスで public: を緩めています

  • この例では、DerivesFrom が何か役に立つかどうかはすぐにはわかりません。ただし、私たちのアーキテクチャではそうであり、それが必要であることを信頼する必要があります。

  • DLL_FLAG はマクロであり、コードのコンパイル時に

さて、問題:

LibraryA では、MyClass と MyCommonClass がエクスポートされます。MyCommonClass がエクスポートされるため、DerivesFrom もエクスポートされます (少なくとも VS2012 ではそう表示されます)。

次に、LibraryB が MyClass をエクスポートすると、DerivesFrom (wtf?) もエクスポートされます。

次に、(cmake によって定義されたビルド プロセスの一部として) MyExecutable.exe を LibraryA.dll および LibraryB.dll に対してリンクすると、重複した DerivesFrom (各ライブラリから 1 つ) があるため失敗します。

以前に見た、使用できないソリューション:

__declspec(dllexport) DerivesFrom を 1 つのライブラリで、インポートを別のライブラリで行います。ただし、これには、実際には存在しないはずのコードが多すぎます。次に、1 つのライブラリがクラスを「ホスト」するように強制しますが、その概念は私たちのシステムでは意味がありません。

「それをしないでください。」まあ、私は Visual Studio がそれをすべきではないと言います。または、DerivesFrom (および DerivesFrom のすべてのインスタンス化) が内部リンケージのみを持ち、そのシンボルがエクスポートされないように指定できる必要があります。

私は途方に暮れています:

  • VS2012 がテンプレートを自動エクスポートし、各ライブラリが独自のものを使用することを拒否する理由。

  • これらのテンプレートをエクスポートしないように指示できないのはなぜですか (DerivesFrom<> を持つクラスから 2 つのライブラリが派生する場合があるため、実行できない場合があります)。

  • この問題を回避する方法。

Any ideas would be greatly appreciated!

4

0 に答える 0