Предотвращение создания экземпляров шаблона в статической библиотеке

Я пытаюсь создать статическую библиотеку, содержащую определения тем 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.

Проблема не возникает, если я строю все в одном проекте, но это не идеальное решение.


person endorph    schedule 01.11.2016    source источник


Ответы (1)


То, что вам нужно сделать, чтобы использовать внешние шаблоны, немного отличается. Действительно, объявление внешнего шаблона предотвратит его создание. Но вам понадобится экземпляр где-то. Это где-то обычно находится в 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, содержащий экземпляры вашего шаблона. Они будут существовать только там.

Не забывайте, что вам все еще нужно сделать реализацию вашего шаблона видимой в заголовке, если вы хотите, чтобы пользователи вашей библиотеки использовали ваш класс шаблона со своими.

person Guillaume Racicot    schedule 01.11.2016