我有一个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()
{
// ...
}
在这种情况下,我得到compilaton错误,说“不允许定义dllimport功能”。我知道是什么导致了这个问题,我明白了。使用我的类库项目的其他项目将MYLIB_EXPORT关键字转换为__declspec(dllimport)。因此,他们期望在DLL中定义MyClass的方法。但是,编译器会在标头内看到定义。
如何克服这种情况并能够导出我的类库项目中定义的模板类?
答案 0 :(得分:4)
未实例化的模板无法直接编译 - 它们是代码生成器,因此它们实际上只有在实例化时才会转换为二进制指令;因此,您无法以“二进制形式”导出模板,就像它是“常规”函数/类一样(另一方面,至少在理论上您可以导出模板的实例化)。
长话短说:只需将模板留在标题库中即可供库客户使用。
请注意,这就是您将模板保留在标头中的确切原因,并且通常不会将其实现与.cpp
文件分开。
答案 1 :(得分:0)
只需删除模板类上的 语句即可。然后,您可以在类外定义类函数(但仍在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修复了它。希望这个答案可以节省其他人的时间: - )