【问题标题】:How to dllexport a class derived from std::runtime_error?如何导出从 std::runtime_error 派生的类?
【发布时间】:2014-07-01 13:22:05
【问题描述】:

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

#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'

不幸的是,我对 Microsoft 风格的文档有些过敏:过于冗长,而且不是很中肯。它一直让我对解决问题的实际期望感到完全困惑。

有谁能给我解惑?我可以只删除基类,但随后捕获 std::runtime_errorstd::exception 不会捕获我的自定义异常类,我非常希望这是可能的。所以……?

【问题讨论】:

    标签: c++ windows exception dll dllexport


    【解决方案1】:

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

    1. 导出它。
    2. 忽略它。
    3. 内嵌。

    请记住,从 dll 导出类的“正确”方法是导出整个类,包括基类和成员,这一点很重要。出于这个原因,有几种技术,如this one on CodeProject,使用“接口”和适当的工厂来创建类(和匹配的破坏)。

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

    取自Microsoft Connect site here (webarchive),这些错误家族本质上是噪声;

    我建议首先避免这种情况 - 将 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 {
        /*...*/
    };
    

    【讨论】:

    • @DevSolar 差不多,只要注意不要更改编译器选项和与标准库相关的定义(迭代器调试等),你应该没问题。
    • 确实是这样,而std::runtime_error 不是。是的,微软把这个搞砸了。 (我更喜欢从std::runtime_error 派生,因为char const * 构造函数,缺少std::exception,这使得事情这么多更容易。我知道为什么我更喜欢避免在Windows 上编码...)
    • microsoft connect 链接指向登录页面,但没有什么用处。
    • @sqeaky。我会尝试找到一个公开可见的版本,如果你有 live.com 或 outlook.com 等帐户,你可以使用它。关键位是答案思想中的引用部分。 VS2015的改动不要在上面评论。
    • @Sqeaky。看起来原来的问题已被删除,它是针对 VS2010 的,所以我并不感到惊讶。我找到了一个网络存档链接并添加了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2022-12-20
    • 1970-01-01
    • 1970-01-01
    • 2011-04-16
    • 2010-12-06
    • 1970-01-01
    相关资源
    最近更新 更多