std :: vector需要让dll-interface被类'X <T>警告的客户端使用

jma*_*erx 45 c++ dll

我正在尝试将我的库导出为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();
};
Run Code Online (Sandbox Code Playgroud)

我得到这样的警告:

警告57警告C4251:'AguiEvent :: events':类'std :: vector <_Ty>'需要让dll接口供'AguiEvent'类的客户端使用

我试图找到如何正确地做到这一点,但MSDN的文档非常适合Windows,我需要这是跨平台的,这样它只能在实际定义AGUI_CORE_DECLSPEC时执行MS特定的东西.

我该怎么做才能摆脱这些警告?

谢谢

Ste*_*end 38

从DLL导出是特定于平台的.您必须为Windows修复此问题(基本上declspec(dllexport/dllimport)在实例化的类模板上使用)并在Windows特定的预处理器宏中封装所需的代码.

我的经验是,从Windows上的DLL导出STL类充满了痛苦,通常我尝试设计界面,这样就不需要了.

  • 有关为什么我仍然会收到有关私有类变量的错误的任何见解?该类已导出,但我希望私有方法和对象不会触发此警告... (11认同)
  • 可能是因为私有的大小影响了出口类的规模.它不是公共接口的一部分,因为它不能直接访问,但如果它作为成员按值出现在导出的类中,它仍然构成它的一部分.尝试用指针握住它或隐藏在pimpl背后.(所有这些只是猜测). (4认同)

cez*_*tko 35

一个修复是依赖于STL结构的动态分配/释放.所以:

class EXPORTED ExportedClass
{
private:
    std::vector<int> *_integers;
public:
    ExportedClass()
    {
        _integers = new std::vector<int>();
    }
    ~ExportedClass()
    {
        delete _integers;
    }
};
Run Code Online (Sandbox Code Playgroud)

如果您要分发必须与可能具有不同版本的STL的不同版本的编译器一起使用的相同二进制文件(dll),则不会给出任何警告并且它更安全.通过这种方式,您可以100%保证sizeof(ExportedClass)始终相同.

  • @AxP可以使用它但是在分发使用c ++标准库编译的共享库时可能遇到类似问题,该库标准库ABI与目标系统上存在的共享指针不兼容 (2认同)

fra*_*ast 10

您可以只导出dll-clients需要访问的成员.为此,请从类声明中删除导出声明,并将其添加到要导出的每个单独的成员函数中.

编辑:

在您的情况下,您可能不应该尝试导出类(省略AGUI_CORE_DECLSPEC),因为它是模板类.提供标题中的所有方法作为内联,它将起作用.

如果您不想这样,一些编译器提供了一种特殊的方法来导出模板类.但是您必须为此指定模板参数.