Я создал библиотеку, предоставляющую класс исключения, полученный из стандартного исключения:
#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'
,
И, к сожалению, у меня есть некоторая аллергия на документацию в стиле Microsoft: чрезмерно многословно, и не очень точно. Это постоянно оставляет меня в замешательстве в отношении того, что на самом деле от меня ожидают, чтобы решить мою проблему.
Кто-нибудь из вас может просветить меня? Я мог бы просто бросить базовый класс, но потом ловить std::runtime_error
или же std::exception
не поймал бы мой класс исключений, и я бы предпочел, чтобы это было возможно. Так…?
Есть несколько вариантов для вас в такой ситуации.
Важно помнить, что «правильный» способ экспортировать класс из DLL — это экспортировать весь класс, включая базы и члены. По этой причине есть несколько методов, таких как этот на CodeProject, которые используют «интерфейс» и соответствующую фабрику для создания класса (и соответствующего уничтожения).
Это не слишком полезно для вас в этой ситуации, пытаясь экспортировать std::runtime_error
вероятно, потребуется больше усилий и, вероятно, будет представлять еще большие проблемы в дальнейшем.
Взято из Сайт Microsoft Connect здесь (Веб-архив), семейство этих ошибок по сути шумовое;
Во-первых, я рекомендую избегать этого — размещение типов STL в интерфейсе вашей DLL заставляет вас играть по правилам STL (в частности, вы не можете смешивать разные основные версии VC, и ваши настройки IDL должны совпадать). Тем не менее, есть обходной путь. C4251 по сути является шумом и может быть …
Стефан Т. Лававей (один из хранителей библиотеки C ++ от Micrsoft).
До тех пор, пока параметры компилятора не изменяются в рамках проекта, просто отключить это предупреждение должно быть прекрасно.
Последний вариант — определить BaseException
класс встроенный и не экспортировать его вообще.
По моему опыту, встроенная опция почти всегда была самой легкой для классов исключений.
Изменения в среде выполнения C ++ для VS2015 привели к изменениям в экспорте std::exception
(Он не экспортируется из среды выполнения).
Встроенный вариант теперь кажется наиболее подходящим в настоящее время (ваш пробег может отличаться).
class Exception : exception {
public:
char const* what() const override;
};
inline char const* Exception::what() const {
/*...*/
};