我正在尝试将我的库导出为DLL,但是我为使用std :: vector的一个特定类获取了很多这些警告:
template <typename T>
class AGUI_CORE_DECLSPEC AguiEvent {
typedef void (*AguiCallbackFptr)(T arg, AguiWidget* sender);
std::vector<AguiCallbackFptr> events;
public:
void call(AguiWidget* sender, T arg) const;
void addHandler(AguiCallbackFptr proc);
void removeHandler(AguiCallbackFptr proc);
void removeHandler();
AguiEvent();
};
我收到这样的警告:
警告57警告C4251: 'AguiEvent :: events':类 '的std ::矢量&lt;&_Ty GT;'需要有 dll-interface供客户使用 'AguiEvent'等级
我试图找到如何正确地做到这一点,但是MSDN的文档非常适用于Windows,我需要将它作为跨平台,以便在实际定义AGUI_CORE_DECLSPEC时它只执行MS特定的东西。
我该怎么做才能摆脱这些警告?
由于
答案 0 :(得分:37)
从DLL导出是特定于平台的。您必须fix this for Windows(基本上在实例化的类模板上使用declspec(dllexport/dllimport)
)并将所需的代码封装在特定于Windows的预处理器宏中。
我的经验是,在Windows上从DLL导出STL类充满了痛苦,通常我会尝试设计界面,这样就不需要了。
答案 1 :(得分:32)
一个修复依赖于STL结构的动态分配/释放。所以:
class EXPORTED ExportedClass
{
private:
std::vector<int> *_integers;
public:
ExportedClass()
{
_integers = new std::vector<int>();
}
~ExportedClass()
{
delete _integers;
}
};
如果您要分发必须与可能具有不同版本的STL的不同版本的编译器一起使用的相同二进制文件(dll),将不会给出任何警告并且它更安全。通过这种方式,您可以100%保证sizeof(ExportedClass)
始终相同。
答案 2 :(得分:7)
您可以导出dll-clients需要访问的成员。为此,请从类声明中删除导出声明,并将其添加到要导出的每个单独成员函数中。
修改强>
在您的情况下,您可能不应该尝试导出类(省略AGUI_CORE_DECLSPEC),因为它是模板类。将标题中的所有方法设置为内联,它将起作用。
如果您不想这样,一些编译器提供了一种导出模板类的特殊方法。但是你必须为此指定模板参数。
答案 3 :(得分:2)
处理这类平台特定内容的常用方法是尝试将所有平台特定设置限制为少数低级文件/类,然后使用#defines和#ifdef / #ifndef预处理程序指令添加/替换平台特定的变化。
要有效地实现这一点,您可能需要一个抽象层。例如,我在20世纪90年代工作的生产系统有一个“文件系统”库。这提供了应用程序和生产代码的通用接口,但必须依赖于一些特定于平台的文件。除了使编译和维护更容易之外,还可以更轻松地移植到新平台。新的文件硬件供应商或OS风格?只需将设置添加到包含文件并相应地添加新指令。