У меня есть проект библиотеки классов C ++, который обычно используется другими проектами C ++. Чтобы иметь возможность использовать классы внутри моего проекта библиотеки классов, я написал файл заголовка, как в примере, приведенном ниже
#pragma once
#ifdef MYLIB
# define MYLIB_EXPORT __declspec(dllexport)
#else
# define MYLIB_EXPORT __declspec(dllimport)
#endif
Нет проблем, пока я не хочу создать шаблонный класс внутри моего проекта библиотеки классов. Проблема в том, что я не могу экспортировать свой шаблонный класс.
MyClass.h
template<class T>
class MYLIB_EXPORT MyClass
{
void myMethod();
// ...
}
template<class T>
void MyClass::myMethod()
{
// ...
}
В этом случае я получаю ошибки компиляции, говорящие «определение функции dllimport не разрешено». Я знаю, что вызывает проблему, и я понимаю это. Другие проекты, использующие мой проект библиотеки классов, преобразуют ключевое слово MYLIB_EXPORT в __declspec (dllimport). Поэтому они ожидают, что методы MyClass будут определены в DLL. Но затем компилятор видит определение в заголовке.
Как я могу преодолеть эту ситуацию и быть в состоянии экспортировать мои классы шаблона, которые определены в моем проекте библиотеки классов?
Необоснованные шаблоны не могут быть скомпилированы напрямую — они генераторы кода, поэтому они фактически переводятся в двоичные инструкции только тогда, когда они создаются; по этой причине вы не можете экспортировать шаблон «в двоичном виде», как если бы это была «обычная» функция / класс (с другой стороны, по крайней мере, теоретически вы можете экспортировать экземпляр шаблона).
Короче говоря: просто оставьте шаблоны в заголовке для включения клиентами библиотеки.
Обратите внимание, что именно поэтому вы держите шаблоны в заголовках и обычно не разделяете их реализацию в .cpp
файлы.
Просто удалите утверждение по шаблону класса. Затем вы можете определить функции класса вне класса (но все еще в MYLIB_EXPORT
*.h
или же *.hpp
файлы заголовков).
MyClass.h
template <typename T>
class MyClass // MYLIB_EXPORT removed
{
void myMethod();
// ...
};
template <typename T>
void MyClass<T>::myMethod()
{
// ...
}
Я получил эту проблему. После долгого времени я понял, что удаление MYLIB_EXPORT исправило это. Надеюсь, что этот ответ сэкономит время другим 🙂