Прямо сейчас я использую libjpegдля сохранения изображений в формате JPEG. Если есть ошибка, libjpeg по умолчанию вызывает exit()
, чего я хочу избежать, поскольку это не фатальная ошибка для моей программы. libjpeg позволяет вам использовать собственный менеджер ошибоки требует, чтобы при использовании собственной функции error_exit()
(которая по умолчанию вызывает exit()
) вы не долженне возвращать управление вызывающей стороне. libjpeg предлагает использовать setjmp.hдля выполнения этого требования, а не exit()
программу.
Однако я пишу программу на C++ и имею доступ к исключениям. В ответе на этот вопросговорится, что безопасно (как и при четко определенном поведении) генерировать исключение из обратного вызова. Но в нем не упоминаются динамические библиотеки, и существует общее практическое правило: вы не создаете исключения за пределами границ динамической библиотеки.
Вот пример:
#include
#include
#include
#include
static void handleLibJpegFatalError(j_common_ptr cinfo)
{
(*cinfo->err->output_message)(cinfo);
throw std::runtime_error("error in libjpeg, check stderr");
}
int main()
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE* file = std::fopen("out.jpeg", "wb"); // assume this doesn't fail for this example
try
{
cinfo.err = jpeg_std_error(&jerr);
jerr.error_exit = handleLibJpegFatalError;
// let's say this triggers a fatal error in libjpeg and handleLibJpegFatalError() is called
// by libjpeg
jpeg_create_compress(&cinfo);
}
catch (...)
{
std::cerr << "Error saving the JPEG!\n";
}
jpeg_destroy_compress(&cinfo);
std::fclose(file);
}
Я хотел бы знать следующее: могу ли я сгенерировать исключение из этого обратного вызова и перехватить его в своем приложении, даже если libjpeg скомпилирован как динамическая библиотека?libjpeg может быть статической или динамической библиотекой, и если это динамическая библиотека, она может быть собрана с помощью другого компилятора. Однако код, который генерирует и перехватывает исключение, обязательно будет находиться в одной и той же единице компиляции. Безопасен ли приведенный выше код?
К вашему сведению, я разрабатываю для OS X и Windows (и помню будущие возможности Linux), поэтому меня больше интересует, известно ли это как четко определенное поведение в целом, а не для конкретной платформы/компилятора.