如何导出从std::runtime_error派生的类

How to dllexport a class derived from std::runtime_error?

本文关键字:error 派生 runtime 何导出 std      更新时间:2023-10-16

我已经建立了一个库,提供了一个从标准异常派生的异常类:

#include <stdexcept>
#include <string>
class BaseException : public std::runtime_error
{
    public:
        BaseException( std::string const & msg );
};

到目前为止,一切顺利。在Unix上编译和处理得相当好。现在我正在准备将其编译成Windows DLL:

#ifdef WIN32
#define MY_EXPORT __declspec(dllexport)
#else
#define MY_EXPORT
#endif
#include <stdexcept>
#include <string>
class MY_EXPORT BaseException : public std::runtime_error
{
    public:
        BaseException( std::string const & msg );
};

然而,这给了我警告C4275: non – DLL-interface class 'std::runtime_error' used as base for DLL-interface class 'BaseException' .

不幸的是,我对微软风格的文档有点过敏:过于啰嗦,而且不是很切题。它一直让我完全困惑,不知道到底需要我做些什么来解决我的问题。

你们谁能给我点化一下吗?我可以只是放弃基类,但然后捕获std::runtime_errorstd::exception不会捕获我的自定义异常类,我非常希望这是可能的。所以…?

在这种情况下,您有几个选择。

  1. 出口。
  2. 忽略它。
  3. 在线。
重要的是要记住,从dll导出类的"正确"方法是导出整个类,包括基类和成员。由于这个原因,有一些技术,比如CodeProject上的这个,使用"接口"和适当的工厂来创建类(以及匹配的销毁)。

在这种情况下,这对您来说不是很有用,尝试导出std::runtime_error可能会花费更多的精力,并且可能会在以后引入更大的问题。

摘自Microsoft Connect网站(webbarchive),这些错误基本上都是噪音;

我建议首先避免这种情况-将STL类型放在DLL的接口中会迫使您按照STL的规则进行操作(特别是,您不能混合不同的VC主要版本,并且您的IDL设置必须匹配)。然而,有一种变通方法。C4251本质上是噪声,可以静音…

Stephan T. Lavavej(微软c++库的维护者之一).

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

最后一个选项是内联定义BaseException类,根本不导出它。

根据我的经验,对于异常类来说,内联选项几乎总是最简单的。


VS2015的c++运行时的变化,导致std::exception的导出发生了变化(它不会从运行时导出)。

内联选项现在似乎是最合适的(您的实际情况可能会有所不同)。

class Exception : exception {
public:
    char const* what() const override;
};
inline char const* Exception::what() const {
    /*...*/
};