我正在使用C++ JPEG库(libjpeg),我意识到当某些函数失败时,调用exit()并关闭应用程序.如何覆盖此行为并阻止应用程序关闭libjpeg错误?
zak*_*ter 20
这是默认行为libjpeg.为了使用libjpeg处理错误,您必须定义一个错误处理例程,如下所示:
struct jpegErrorManager {
/* "public" fields */
struct jpeg_error_mgr pub;
/* for return to caller */
jmp_buf setjmp_buffer;
};
char jpegLastErrorMsg[JMSG_LENGTH_MAX];
void jpegErrorExit (j_common_ptr cinfo)
{
/* cinfo->err actually points to a jpegErrorManager struct */
jpegErrorManager* myerr = (jpegErrorManager*) cinfo->err;
/* note : *(cinfo->err) is now equivalent to myerr->pub */
/* output_message is a method to print an error message */
/*(* (cinfo->err->output_message) ) (cinfo);*/
/* Create the message */
( *(cinfo->err->format_message) ) (cinfo, jpegLastErrorMsg);
/* Jump to the setjmp point */
longjmp(myerr->setjmp_buffer, 1);
}
Run Code Online (Sandbox Code Playgroud)
然后使用注册jpeg_std_error.
FILE* fileHandler;
/* ... */
struct jpeg_decompress_struct cinfo;
jpegErrorManager jerr;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = jpegErrorExit;
/* Establish the setjmp return context for my_error_exit to use. */
if (setjmp(jerr.setjmp_buffer)) {
/* If we get here, the JPEG code has signaled an error. */
cerr << jpegLastErrorMsg << endl;
jpeg_destroy_decompress(&cinfo);
fclose(fileHandler);
return 1;
}
Run Code Online (Sandbox Code Playgroud)
你可以在这里找到一个完整的例子.
由于问题是针对C++,另一种方法是例外:
错误处理程序
void jpegErrorExit ( j_common_ptr cinfo )
{
char jpegLastErrorMsg[JMSG_LENGTH_MAX];
/* Create the message */
( *( cinfo->err->format_message ) ) ( cinfo, jpegLastErrorMsg );
/* Jump to the setjmp point */
throw std::runtime_error( jpegLastErrorMsg ); // or your preffered exception ...
}
Run Code Online (Sandbox Code Playgroud)
用它:
FILE* fileHandler;
/* ... */
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error( &jerr );
jerr.error_exit = jpegErrorExit;
try {
jpeg_create_decompress( &cinfo );
jpeg_stdio_src( &cinfo, fileHandler );
/// ...
jpeg_destroy_decompress( &cinfo );
fclose( fileHandler );
}
catch ( std::runtime_exception & e ) {
jpeg_destroy_decompress( &cinfo );
fclose( fileHandler );
throw; // or return an error code
}
Run Code Online (Sandbox Code Playgroud)
使用 c++11 我使用 lambda 实现了这个(类似于 Marco 的答案):
[](j_common_ptr cinfo){throw cinfo->err;}
Run Code Online (Sandbox Code Playgroud)
效果很好。只有这样才能抓住'struct jpeg_error_mgr *err'
IE
struct jpeg_error_mgr jerr_mgr;
cinfo.err = jpeg_std_error(&jerr_mgr);
jerr_mgr.error_exit = [](j_common_ptr cinfo){throw cinfo->err;};
Run Code Online (Sandbox Code Playgroud)
和
try
{
jpeg_create_decompress(&cinfo);
...
}
catch (struct jpeg_error_mgr *err)
{
char pszErr[1024];
(cinfo.err->format_message)((j_common_ptr)&cinfo, pszErr);
...
}
Run Code Online (Sandbox Code Playgroud)