C++ std::vector 需要具有类“X<T>”警告的客户端使用的 dll 接口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4145605/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
std::vector needs to have dll-interface to be used by clients of class 'X<T> warning
提问by jmasterx
I'm trying to make my library exportable as a DLL but I'm getting a lot of these warnings for one specific class that uses std::vector:
我正在尝试使我的库可以作为 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();
};
I get warnings like these:
我收到这样的警告:
Warning 57 warning C4251: 'AguiEvent::events' : class 'std::vector<_Ty>' needs to have dll-interface to be used by clients of class 'AguiEvent'
警告 57 警告 C4251:“AguiEvent::events”:“std::vector<_Ty>”类需要具有 dll 接口才能被“AguiEvent”类的客户端使用
I tried to find how to do this properly but MSDN's documentation is very Windows Only, and I need this to be cross platform so that it only does MS specific stuff when AGUI_CORE_DECLSPEC is in fact defined.
我试图找到如何正确执行此操作,但 MSDN 的文档仅适用于 Windows,并且我需要它是跨平台的,以便它仅在实际定义 AGUI_CORE_DECLSPEC 时才执行特定于 MS 的操作。
What should I do to get rid of these warnings?
我应该怎么做才能摆脱这些警告?
Thanks
谢谢
采纳答案by Steve Townsend
Exporting from a DLL is platform-specific. You will have to fix this for Windows(basically use declspec(dllexport/dllimport)
on the instantiated class template) and encapsulate the required code in your Windows-specific preprocessor macro.
从 DLL 导出是特定于平台的。您必须针对 Windows 修复此问题(主要用于declspec(dllexport/dllimport)
实例化的类模板)并将所需的代码封装在 Windows 特定的预处理器宏中。
My experience is that exporting STL classes from DLLs on Windows is fraught with pain, generally I try to design the interface such that this is not needed.
我的经验是,从 Windows 上的 DLL 导出 STL 类充满痛苦,通常我会尝试设计不需要的接口。
回答by ceztko
One fix is relying on dynamic allocation/deallocation of the STL structures. So:
一种解决方法是依赖 STL 结构的动态分配/解除分配。所以:
class EXPORTED ExportedClass
{
private:
std::vector<int> *_integers;
public:
ExportedClass()
{
_integers = new std::vector<int>();
}
~ExportedClass()
{
delete _integers;
}
};
won't give any warning and it's more safe in case you are distributing the same binary (the dll) that has to be used with different version of the compiler that may has different versions of the STL. In this way you have 100% guarantee that sizeof(ExportedClass)
is always the same.
不会给出任何警告,而且如果您分发相同的二进制文件(dll),该二进制文件必须与可能具有不同 STL 版本的不同版本的编译器一起使用,则更安全。通过这种方式,您可以 100% 保证sizeof(ExportedClass)
始终相同。
回答by frast
You could just export the members, which the dll-clients need to access. To do this remove the export declaration from the class declaration and add it to each individual member function you want to export.
您可以只导出 dll 客户端需要访问的成员。为此,请从类声明中删除导出声明,并将其添加到您要导出的每个成员函数中。
EDIT:
编辑:
In your case you should probably not try to export the class (leave out AGUI_CORE_DECLSPEC) since it is a template class. Provide all methods in your header as inline and it will work.
在您的情况下,您可能不应该尝试导出该类(省略 AGUI_CORE_DECLSPEC),因为它是一个模板类。将标题中的所有方法提供为内联方法,它将起作用。
If you do not want this, some compilers provide a special way to export template classes. But you will have to specify the template parameter for this.
如果您不希望这样,一些编译器提供了一种特殊的方式来导出模板类。但是您必须为此指定模板参数。
回答by winwaed
The usual method of dealing with platform specific stuff like this is to try and restrict all platform specific settings to a handful of low level files/classes, and then use #defines and #ifdef/#ifndef preprocessor directives to add/replace platform specific variations.
处理此类特定于平台的内容的常用方法是尝试将所有特定于平台的设置限制为少数低级文件/类,然后使用 #defines 和 #ifdef/#ifndef 预处理器指令添加/替换特定于平台的变体.
To effectively implement this, you may need an abstraction layer. For example a production system I worked on in the 1990s had a "File System" library. This presented a common interface to the applications and production code, but had to rely on a few platform-specific files. As well as making it easier to compile and maintain, it also made it easier to port to new platforms. A new file hardware vendor or OS flavour? Simply add the settings to the include files and add new directives accordingly.
为了有效地实现这一点,您可能需要一个抽象层。例如,我在 1990 年代使用的生产系统有一个“文件系统”库。这为应用程序和生产代码提供了一个通用接口,但必须依赖一些特定于平台的文件。除了使编译和维护更容易,它还使移植到新平台变得更容易。新的文件硬件供应商或操作系统风格?只需将设置添加到包含文件并相应地添加新指令。