导出DLL接口中包含相同类的STL类成员

Export a STL class member containing the same class in a DLL interface

本文关键字:STL 成员 同类 包含相 DLL 接口 导出      更新时间:2023-10-16

假设我有一个在STL容器中引用自身的类:

class __declspec(dllexport) Widget {
protected:
    std::vector<Widget *> children;
}

如果我说intvector,在类定义之前,我可以有以下内容:

template class __declspec(dllexport) std::vector<int>;

应该可以工作。但如果类还没有定义,我该怎么做呢?前向声明类:

class Widget;
template class __declspec(dllexport) std::vector<Widget *>;

不能消除我从MSVC得到的警告,它是;

warning C4251: 'Widget::children' : class 'std::vector<Widget *,std::allocator<_Ty>>' needs to have dll-interface to be used by clients of class 'Widget'

我相信警告本身的信息在某种程度上是相关的,但我不确定究竟如何进行

从这里开始,这些错误族本质上是噪音;

C4251本质上是噪声,可以消声
- Stephan T. Lavavej(微软c++库的维护者之一).

只要编译器选项在整个项目中是一致的,只是沉默这个警告应该是好的。

作为一个更全面的替代,您可以查看pimpl模式并从类定义中删除std::vector,因此它不需要从dll中导出。

class __declspec(dllexport) Widget {
protected:
    struct Pimpl;
    Pimpl* pimpl_;
}

// in the cpp compiled into the dll
struct Widget::Pimpl {
    // ...
    std::vector<Widget*> children;
    // ...
}

MSDN对此有一篇很好的文章,作为c++ 11新特性介绍的一部分。

一般来说,在dll接口中不使用std类更容易,特别是在需要互操作性的情况下。

警告本身确实是相关的。其中提到的头文件安装在与我正在处理的目录不同的目录中,因此看不到我的更改。修复该警告的正确方法是:

class Widget;
template class __declspec(dllexport) std::vector<Widget *>;

在类定义之前