問題があります。次のようなクラス構造があります。
// 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!