在C回调中的C ++中引发异常,可能会跨越动态库边界……是否安全?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C回调中的C ++中引发异常,可能会跨越动态库边界……是否安全?相关的知识,希望对你有一定的参考价值。
我现在正在使用libjpeg保存JPEG图像。如果有错误,libjpeg的默认行为是调用exit()
,我想避免这种错误,因为这对我的程序来说不是致命错误。 libjpeg allows you to use your own error manager,并要求如果使用自己的error_exit()
函数(默认情况下会调用exit()
),则必须不能将控制权交还给调用者。 libjpeg建议使用setjmp.h来满足此要求,而不要使用exit()
该程序。
但是,我正在编写C ++程序,并且可以访问异常。 This question's answer声明从回调中引发异常是安全的(如定义良好的行为)。但是它没有提到动态库,并且有一个普遍的经验法则,即不要跨动态库边界抛出异常。
这里是一个例子:
#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!
";
}
jpeg_destroy_compress(&cinfo);
std::fclose(file);
}
[[我想知道的是:即使libjpeg被编译为动态库,我也可以从此回调中引发异常并将其捕获到我的应用程序中吗? libjpeg可以是静态库或动态库,如果它是动态库,则可能使用其他编译器来构建。但是,引发并捕获异常的代码肯定会在同一编译单元中。 以上代码安全吗?
FYI,我正在为OS X和Windows进行开发(并牢记Linux的未来可能性),所以我更感兴趣的是,这通常是否是定义良好的行为,而不是针对特定行为平台/编译器。您应该遵循文档,并使用setjmp
/ longjmp
移至libjpeg代码的调用之外,如果要使用异常,请立即在if (setjmp(...)) { ... }
正文中引发异常。
以上是关于在C回调中的C ++中引发异常,可能会跨越动态库边界……是否安全?的主要内容,如果未能解决你的问题,请参考以下文章
从完成处理程序/块中引发自定义异常会使目标 c 中的应用程序崩溃