#c #windows #exception #dll #dllexport
#c #Windows #исключение #dll #dllexport
Вопрос:
Я настроил библиотеку, предоставляющую класс исключений, производный от стандартного исключения:
#include <stdexcept>
#include <string>
class BaseException : public std::runtime_error
{
public:
BaseException( std::string const amp; 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 amp; msg );
};
Однако это выдает мне предупреждение C4275: non – DLL-interface class 'std::runtime_error' used as base for DLL-interface class 'BaseException'
.
И, к сожалению, у меня некоторая аллергия на документацию в стиле Microsoft: чрезмерно многословная и не очень по существу. Это оставляет меня в полном замешательстве относительно того, что на самом деле ожидается от меня для решения моей проблемы.
Кто-нибудь из вас может меня просветить? Я мог бы просто удалить базовый класс, но тогда перехват std::runtime_error
или std::exception
не перехват моего пользовательского класса исключений, и я бы очень предпочел, чтобы это было возможно. Итак …?
Ответ №1:
В подобной ситуации для вас есть несколько вариантов.
- Экспортируйте его.
- Игнорируйте это.
- Встроить его.
Важно иметь в виду, что «правильный» способ экспортировать класс из библиотеки DLL — экспортировать весь класс, включая базы и члены. По этой причине существует несколько методов, таких как этот в CodeProject, которые используют «интерфейс» и соответствующую фабрику для создания класса (и соответствующего уничтожения).
Это не слишком полезно для вас в этой ситуации, попытка экспорта std::runtime_error
, вероятно, требует больше усилий и, вероятно, приведет к еще большим проблемам позже.
Взято с сайта Microsoft Connect здесь (webarchive), семейство этих ошибок по сути являются шумом;
Я рекомендую избегать этого в первую очередь — размещение типов STL в интерфейсе вашей DLL заставляет вас играть по правилам STL (в частности, вы не можете смешивать разные основные версии VC, и ваши настройки IDL должны совпадать). Однако есть обходной путь. C4251 — это, по сути, шум, и его можно отключить…
Стефан Т. Лававей (один из сопровождающих библиотеки Micrsoft для C ).
Пока параметры компилятора согласованы в проекте, просто отключить это предупреждение должно быть просто отлично.
Последний вариант — определить BaseException
класс встроенным и вообще не экспортировать его.
По моему опыту, встроенный вариант почти всегда оказывался самым простым для классов исключений.
Изменения в среде выполнения C для VS2015 привели к изменениям в экспорте std::exception
(он не экспортируется из среды выполнения).
Встроенный вариант теперь кажется наиболее подходящим на данный момент (ваш пробег может отличаться).
class Exception : exception {
public:
char const* what() const override;
};
inline char const* Exception::what() const {
/*...*/
};
Комментарии:
1. @DevSolar В значительной степени, просто помните, чтобы не изменять параметры компилятора и определения, связанные со стандартной библиотекой (отладка итератора и т.д.), И все должно быть в порядке.
2. И действительно, это так, хотя
std::runtime_error
этого нет. Да, Microsoft облажалась с этим. (Я предпочитаю выводить offstd::runtime_error
из-заchar const *
конструктора, которыйstd::exception
отсутствует и который намного упрощает работу. Я знаю, почему я предпочитаю избегать кодирования в Windows …)3. Ссылка Microsoft connect ведет на страницу входа, а не на что-то полезное.
4. @sqeaky. Я попытаюсь найти общедоступную видимую версию, если у вас есть live.com или outlook.com и т.д. учетная запись, вы можете использовать это. Ключевой бит — это заключенная в кавычки часть в ответе. Не комментируйте выше изменения в VS2015.
5. @Sqeaky. Похоже, что исходная проблема была удалена, это было для VS2010, поэтому я не так уж удивлен. Я нашел ссылку на веб-архив и добавил ее также.