Я пытаюсь создать статическую библиотеку, содержащую определения тем DDS, полученных из различных файлов IDL. Я использую OpenDDS в качестве промежуточного программного обеспечения.
Когда я создаю файл IDL, содержащий sequence<long>
, скомпилировать его в мою статическую библиотеку, а затем связать статическую библиотеку с моим приложением, я получаю ошибки компоновщика, связанные с множественным определением символов:
Error LNK2005 "public: void __cdecl TAO::unbounded_value_sequence<int>::length(unsigned int)" (?length@?$unbounded_value_sequence@H@TAO@@QEAAXI@Z) already defined in TAO.lib(TAO.dll)
Я полагаю, что это потому, что моя статическая библиотека содержит экземпляр шаблона unbounded_value_sequence
, и мое приложение также содержит экземпляр. Кажется, это происходит из-за ACE TAO, которая используется OpenDDS.
Я ищу способ избежать создания экземпляра шаблона в моей статической библиотеке, чтобы он мог просто использовать определение в приложении, когда они связаны друг с другом. Я попытался добавить следующее:
extern template class TAO::unbounded_value_sequence<int>;
Это привело к следующей ошибке:
Error C2961 'TAO::unbounded_value_sequence<CORBA::Long>': inconsistent explicit instantiations, a previous explicit instantiation did not specify '__declspec(dllimport)'
Я пытался найти это создание, но его нет в моем коде. Это может быть в самом ACE.
Проблема не возникает, если я строю все в одном проекте, но это не идеальное решение.
То, что вы должны сделать, чтобы использовать внешние шаблоны, немного отличается. Действительно, объявление шаблона extern предотвратит его создание. Но вам понадобится инстанциация где-то. Это где-то обычно находится в cpp с именем шаблона, который вы хотите скомпилировать.
unbounded_value_sequence.h:
// template struct here
extern template class TAO::unbounded_value_sequence<int>;
extern template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library
unbounded_value_sequence.cpp:
#include "unbounded_value_sequence.h"
// Here you compile them one time.
template class TAO::unbounded_value_sequence<int>;
template class TAO::unbounded_value_sequence<long>;
// and every other instantiation you want to be in your static library
Это сделает ваш шаблон экземпляром только один раз, внутри вашей библиотеки. Компилятор сгенерирует unbounded_value_sequence
объектный файл, содержащий ваши экземпляры шаблона. Они будут существовать только там.
Не забывайте, что вам все равно нужно сделать реализацию шаблона видимой в заголовке, если вы хотите, чтобы пользователи вашей библиотеки использовали ваш шаблонный класс со своими.
Других решений пока нет …