Я использую libjpeg, чтобы сохранить изображения JPEG. Если есть ошибка, поведение по умолчанию libjpeg - вызвать exit()
, чего я хочу избежать, поскольку это не фатальная ошибка для моей программы. libjpeg позволяет вам использовать собственный диспетчер ошибок и требует, чтобы при использовании вашей собственной функции error_exit()
(которая вызывает exit()
по умолчанию ) вы должны не возвращать управление вызывающему. libjpeg предлагает использовать setjmp.h для удовлетворения этого требования, а не exit()
программы.
Однако я пишу программу на С++, и у меня есть доступ к исключениям. Этот ответ на вопрос утверждает, что он безопасен (как в четко определенном поведении), чтобы вызывать исключение из обратного вызова. Но он не упоминает динамические библиотеки, и существует общее эмпирическое правило, что вы не бросаете исключения через границы динамической библиотеки.
Вот пример:
#include <iostream>
#include <jpeglib.h>
#include <cstdio>
#include <stdexcept>
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 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 может быть статическим или динамической библиотеки, и если это динамическая библиотека, она может быть построена с другим компилятором. Однако код, который выбрасывает и ловит исключение, безусловно, будет в одном модуле компиляции. Безопасен ли этот код?
FYI, я разрабатываю для OS X и Windows (и сохраняю в виду будущее возможности Linux), поэтому меня больше интересует, известно ли, что это хорошо определенное поведение в целом, а не для конкретной платформы/компилятора.