如何dllexport从std :: runtime_error派生的类?

时间:2014-07-01 13:22:05

标签: c++ windows exception dll dllexport

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

#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 );
};

但是,这会给我warning C4275non – DLL-interface class 'std::runtime_error' used as base for DLL-interface class 'BaseException'

不幸的是,我对微软风格的文档有些过敏:过于冗长,并不是非常重要。它让我完全不知道对我解决问题的实际期望是什么。

你们任何人都可以开导我吗?我可以删除基类,但是然后捕获std::runtime_errorstd::exception将无法捕获我的自定义异常类,我非常希望这是可能的。所以...?

1 个答案:

答案 0 :(得分:12)

在这种情况下,您可以选择几种方法。

  1. 导出它。
  2. 忽略它。
  3. 直播吧。
  4. 重要的是要记住,从dll导出类的“正确”方法是导出整个类,包括基类和成员。出于这个原因,有几种技术,如this one on CodeProject,使用“接口”和适当的工厂来创建类(和匹配的销毁)。

    在这种情况下,这对您来说并不太有用,尝试导出std::runtime_error可能需要付出更多努力,并可能在以后引入更大的问题。

    取自Microsoft Connect site herewebarchive),这些错误的家族基本上都是噪音;

      

    我建议首先避免这种情况 - 将STL类型放在DLL的界面中会强制您按照STL的规则进行播放(具体来说,您不能混用VC的不同主要版本,并且您的IDL设置必须匹配)。但是,有一种解决方法。 C4251基本上是噪音,可以沉默......

         

    Stephan T. Lavavej(Micrsoft C ++库的维护者之一)。

    只要编译器选项在整个项目中保持一致,只需将此警告静音即可。

    最后一个选项是内联BaseException类,而不是导出它。

    根据我的经验,内联选项几乎总是最容易的异常类。


    VS2015的C ++运行时中的更改导致std::exception的导出发生更改(不会从运行时导出)。

    现在,内联选项似乎是最合适的(您的里程可能会有所不同)。

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