У меня есть проблема. У меня есть структура классов, которая выглядит примерно так:
// 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<> в нем).
Как обойти эту проблему.
Благодарим за любую идею!
Задача ещё не решена.