Рассмотрим простой класс, который состоит только из встроенных функций-членов. Например:
template <typename T1, typename T2>
class Point2D {
public:
typedef Point2D<T1,T2> ThisType;
typedef T1 Tx;
typedef T2 Ty;
T1 x;
T2 y;
inline Point2D() : x(0), y(0) {}
inline Point2D(T1 nx, T2 ny) : x(nx), y(ny) {}
inline Point2D(const Point2D& b) : x(b.x), y(b.y) {}
inline Point2D& operator=(const Point2D& b) { x=b.x; y=b.y; return *this; }
inline ~Point2D() {}
};
typedef Point2D<int,int> Int2;
Когда объект типа Int2
используется в другом классе (скажем, класс MyClass
член Int2 point
), который я хочу экспортировать в DLL, я получаю следующее предупреждение:
предупреждение C4251: «MyClass :: point»: класс «Point2D» должен иметь dll-интерфейс для использования клиентами класса «MyClass»
Однако, если я поставлю __declspec(dllexport)
в определении «Point2D», как следует из предупреждения (что кажется мне глупым, поскольку все функции встроены, плюс это шаблон, смотри ТАК вопрос), Я получаю следующую ошибку при попытке использовать DLL в другом объекте:
ошибка LNK2019: неразрешенный внешний символ «__declspec (dllimport) public: __thiscall lwin :: Point2D :: Point2D (int, int)» …
Обратите внимание, определение Point2D
дается в заголовке, который виден для всех проектов.
Что я должен делать? Пропустить dllexport
и игнорировать предупреждение? Или есть какая-то хитрая уловка, которая может избежать этой путаницы компилятора?
замещать Int2
член MyClass
с Int2*
член для решения этой проблемы. Создайте Int2
экземпляр в MyClass
конструктор и удалить в MyClass
деструктор.
Шаблонный класс не может быть экспортирован, поэтому вы не можете объявить его как __declspec(dllexport)
, C4251 показан, потому что размер класса контейнера может отличаться, если Dll и его клиент скомпилированы с разными параметрами компиляции, что вызывает неопределенное поведение. С другой стороны, указатель всегда имеет одинаковый размер.
Попробуйте добавить __declspec(dllexport)
/ __declspec(dllimport)
соответственно каждому встроенному методу. Это было бы ошибкой для не шаблонного класса, но классовые классы / функции шаблона, похоже, также требуют добавления этого метода.