问题描述
我建立了一个库,提供从标准异常派生的异常类:
I have set up a library providing an exception class derived from the standard exception:
#include <stdexcept>
#include <string>
class BaseException : public std::runtime_error
{
public:
BaseException( std::string const & msg );
};
到目前为止,一切都很好.在 Unix 上编译和处理得很好.现在我准备将其编译为 Windows DLL:
So far, so good. Compiles and handles quite well on Unix. Now I am prepping this for compilation into a 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:非 DLL 接口类'std::runtime_error' 用作 DLL 接口类 'BaseException'
的基础.
However, this gives me warning C4275: non – DLL-interface class 'std::runtime_error' used as base for DLL-interface class 'BaseException'
.
不幸的是,我对 Microsoft 风格的文档有些过敏:过于冗长,而且不是很切题.它一直让我完全困惑,不知道实际期望我解决什么问题.
And unfortunately, I am somewhat allergic to Microsoft-style documentation: Excessively wordy, and not very to the point. It keeps leaving me utterly confused as to what is actually expected of me to solve my problem.
你们中的任何人都可以启发我吗?我可以删除基类,但随后捕获 std::runtime_error
或 std::exception
不会捕获我的自定义异常类,我更喜欢这样成为可能.所以……?
Can any of you enlighten me? I could just drop the base class, but then catching std::runtime_error
or std::exception
would not catch my custom exception class, and I would very much prefer this to be possible. So...?
推荐答案
在这种情况下,您有几个选择.
There are a few options for you in this type of situation.
- 导出.
- 忽略它.
- 内嵌它.
重要的是要记住,从 dll 导出类的正确"方法是导出整个类,包括基类和成员.出于这个原因,有几种技术,例如 CodeProject 上的这个,使用接口"和适当的工厂来创建类(和匹配的销毁).
It is important to bear in mind that the "correct" way to export class from a dll is to export the entire class, including bases and members. For this reason there are several techniques such as this one on CodeProject, that use an "interface" and appropriate factory to create the class (and matching destruction).
在这种情况下,这对您来说没有太大用处,尝试导出 std::runtime_error
可能更费力,并且可能会在以后引入更大的问题.
This is not too useful for you in this situation, trying to export std::runtime_error
is probably more effort and likely to introduce even bigger issues later on.
取自 此处的 Microsoft Connect 站点(webarchive),这些错误系列本质上是噪音;
Taken from the Microsoft Connect site here (webarchive), the family of these errors are essentially noise;
我建议首先避免这种情况 - 将 STL 类型放在 DLL 的接口中会迫使您遵守 STL 的规则(特别是,您不能混合不同主要版本的 VC,并且您的 IDL 设置必须匹配).但是,有一个解决方法.C4251本质上是噪音,可以静音...
I recommend avoiding this in the first place - putting STL types in your DLL's interface forces you to play by the STL's rules (specifically, you can't mix different major versions of VC, and your IDL settings must match). However, there is a workaround. C4251 is essentially noise and can be silenced...
Stephan T. Lavavej(Micrsoft 的 C++ 库的维护者之一).
Stephan T. Lavavej (one of the maintainer's of Micrsoft's C++ library).
只要编译器选项在整个项目中是一致的,只需忽略此警告就可以了.
So long as the compiler options are consistent through the project, just silencing this warning should be just fine.
最后一个选项是内联定义 BaseException
类并且根本不导出它.
The final option is to define the BaseException
class inline and not export it at all.
根据我的经验,内联选项对于异常类来说几乎总是最简单的.
In my experience, the inline option landed up almost always being the easiest for exception classes.
VS2015 的 C++ 运行时发生了变化,导致 std::exception
的导出发生了变化(它不是从运行时导出的).
Changes in the C++ runtime for VS2015, have resulted in changes to the exporting of std::exception
(It is not exported from the runtime).
inline 选项现在似乎是这个时候最合适的(你的里程可能会有所不同).
The inline option now seems to be the most appropriate at this time (your mileage may vary).
class Exception : exception {
public:
char const* what() const override;
};
inline char const* Exception::what() const {
/*...*/
};
这篇关于如何 dllexport 从 std::runtime_error 派生的类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!