Estoy usando libjpeg ahora mismo para guardar imágenes JPEG. Si hay un error, el comportamiento predeterminado de libjpeg es llamar al exit()
, lo cual quiero evitar ya que no es un error fatal para mi programa. libjpeg allows you to use your own error manager, y exige que si utiliza su propia función error_exit()
(que llama a exit()
de forma predeterminada) debe no devolver el control a la persona que llama. libjpeg sugiere usar setjmp.h para cumplir este requisito y no exit()
el programa.Lanzar una excepción en C++ en una devolución de llamada en C, posiblemente cruzar el límite dinámico de la biblioteca ... ¿es seguro?
Sin embargo, estoy escribiendo un programa en C++, y tengo acceso a excepciones. This question's answer indica que es seguro (como en un comportamiento bien definido) lanzar una excepción desde la devolución de llamada. Pero no menciona las bibliotecas dinámicas, y hay una regla general que no arroja excepciones a través de los límites dinámicos de la biblioteca.
He aquí un ejemplo:
#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'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);
}
Lo que me gustaría saber es: ¿puedo lanzar una excepción de esta devolución de llamada, y ponerse de nuevo en mi solicitud, incluso si libjpeg se compila como una biblioteca dinámica ? libjpeg puede ser una biblioteca estática o dinámica, y si se trata de una biblioteca dinámica, posiblemente se pueda compilar con un compilador diferente. Sin embargo, el código que arroja y atrapa la excepción estará ciertamente en la misma unidad de compilación. ¿Es seguro el código anterior?
FYI, estoy desarrollando para OS X y Windows (y teniendo en cuenta el futuro de una posibilidad de Linux), por lo que estoy más interesado en si esto se sabe que es un comportamiento bien definido en general, y no para una plataforma/compilador específico.
Eso es perfectamente seguro. ¿Por qué no sería? Las llamadas a bibliotecas compartidas aún usan la misma pila de llamadas. –
Esto podría estar relacionado: http: // stackoverflow.com/questions/10318363/is-it-safe-for-xs-error-handler-to-throw-exceptions – Pubby
@nw: No puedo pensar en por qué no sería guardar; Solo quiero asegurarme de que nada se arruine al desenrollar la pila. Puede ser perfectamente seguro, pero me han mordido en el trasero al asumir cosas del pasado, así que estoy jugando seguro aquí y comprobando dos veces. – Cornstalks