在 DLL 接口中导出包含相同 class 的 STL class 成员
Export a STL class member containing the same class in a DLL interface
假设我有一个 class 在 STL 容器中引用自身:
class __declspec(dllexport) Widget {
protected:
std::vector<Widget *> children;
}
如果我说 int
的 vector
,那么在 class 定义之前我可以有以下内容:
template class __declspec(dllexport) std::vector<int>;
这应该会起作用。但是,如果 class 尚未定义,我该怎么做呢?转发声明 class:
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'
我相信警告中的信息本身在某种程度上是相关的,但我不确定具体如何进行。
警告本身确实相关。其中提到的头文件安装在与我正在处理的目录不同的目录中,因此没有看到我的更改。修复警告的正确方法是:
class Widget;
template class __declspec(dllexport) std::vector<Widget *>;
在 class 定义之前。
取自 here,这些错误系列本质上是噪音;
C4251 is essentially noise and can be silenced
- Stephan T. Lavavej (one of the maintainer's of Micrsoft's C++ library).
只要编译器选项在整个项目中保持一致,只需消除此警告就可以了。
作为更全面的替代方案,您可以查看 pimpl pattern 并从 class 定义中删除 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 has a nice article on this 作为 C++11 新特性介绍的一部分。
通常,在 dll interface 中不使用 std
class 会更容易,尤其是在需要互操作性时。
假设我有一个 class 在 STL 容器中引用自身:
class __declspec(dllexport) Widget {
protected:
std::vector<Widget *> children;
}
如果我说 int
的 vector
,那么在 class 定义之前我可以有以下内容:
template class __declspec(dllexport) std::vector<int>;
这应该会起作用。但是,如果 class 尚未定义,我该怎么做呢?转发声明 class:
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'
我相信警告中的信息本身在某种程度上是相关的,但我不确定具体如何进行。
警告本身确实相关。其中提到的头文件安装在与我正在处理的目录不同的目录中,因此没有看到我的更改。修复警告的正确方法是:
class Widget;
template class __declspec(dllexport) std::vector<Widget *>;
在 class 定义之前。
取自 here,这些错误系列本质上是噪音;
C4251 is essentially noise and can be silenced
- Stephan T. Lavavej (one of the maintainer's of Micrsoft's C++ library).
只要编译器选项在整个项目中保持一致,只需消除此警告就可以了。
作为更全面的替代方案,您可以查看 pimpl pattern 并从 class 定义中删除 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 has a nice article on this 作为 C++11 新特性介绍的一部分。
通常,在 dll interface 中不使用 std
class 会更容易,尤其是在需要互操作性时。