OpenCV1.0中錯誤處理與C語言標准函數庫里的錯誤處理相似,設置全局錯誤標識,通過檢查全局錯誤標識,來判斷程序是否出現錯誤,並進行錯誤報告.
在OpenCV1.0中,如果調用函數出現錯誤並不直接返回錯誤代碼,而是用CV_ERROR宏調用cvError函數報錯,並設置錯誤狀態,然后調用標准的或者用戶自定義的錯誤處理器.
每個程序的線程都有一個全局變量,它包含了錯誤狀(一個整數值).這個狀態可以被cvGetErrStatus函數查詢到.
//保存錯誤所在的文件和行 typedef struct { const char* file; int line; }CvStackRecord; //保存當前線程的上下文信息 typedef struct CvContext { int err_code; //錯誤碼 int err_mode; //錯誤處理模式 CvErrorCallback error_callback; //錯誤處理函數指針入口 void* userdata; char err_msg[4096]; CvStackRecord err_ctx; } CvContext; CV_IMPL void cvError( int code, const char* func_name, const char* err_msg, const char* file_name, int line ) { if( code == CV_StsOk ) cvSetErrStatus( code ); else { CvContext* context = icvGetContext(); //獲取當前上下文信息 if( code != CV_StsBackTrace && code != CV_StsAutoTrace ) { //將錯誤信息保存到當前上下文信息 char* message = context->err_msg; context->err_code = code; strcpy( message, err_msg ); context->err_ctx.file = file_name; context->err_ctx.line = line; } if( context->err_mode != CV_ErrModeSilent ) { //調用錯誤處理器進行錯誤處理 int terminate = context->error_callback( code, func_name, err_msg, file_name, line, context->userdata ); if( terminate ) { CV_DBG_BREAK(); //exit(-abs(terminate)); } } } }
OpenCV2.4.1中錯誤處理機制與上述有所不同,雖然對外接口沒有發生變化,但其內部處理方式發生了變化,主要參用C++的異常處理機制.
如果調用函數出現錯誤並不直接返回錯誤代碼,用CV_ERROR宏調用cvError函數,然后在cvError中調用error函數來報告錯誤信息.
在進入error函數之前,新建一個錯誤異常類,來保存當前的錯誤信息,然后利用這個異常類作為error函數的接口.
在error函數內,首先檢測是否存在自定義的錯誤處理器,若存在則進入自定義的錯誤處器處理錯誤,否則,報告錯誤信息,並拋出錯誤異常.
若在錯誤處理處,有異常的捕獲,則可以捕獲該異常,用戶進行相應的處理.相應的代碼如下:
1 #define CV_ERROR( Code, Msg ) \ 2 { \ 3 cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ 4 __CV_EXIT__; \ 5 } 6 CV_IMPL void cvError( int code, const char* func_name, const char* err_msg, const char* file_name, int line ) 7 { 8 cv::error(cv::Exception(code, err_msg, func_name, file_name, line)); 9 } 10 void error( const Exception& exc ) 11 { 12 if (customErrorCallback != 0) //檢測是否存在自定義的錯誤處理器 13 customErrorCallback(exc.code, exc.func.c_str(), exc.err.c_str(), 14 exc.file.c_str(), exc.line, customErrorCallbackData); 15 else 16 { 17 //報告錯誤信息 18 const char* errorStr = cvErrorStr(exc.code); 19 char buf[1 << 16]; 20 sprintf( buf, "OpenCV Error: %s (%s) in %s, file %s, line %d", 21 errorStr, exc.err.c_str(), exc.func.size() > 0 ? 22 exc.func.c_str() : "unknown function", exc.file.c_str(), exc.line ); 23 fprintf( stderr, "%s\n", buf ); 24 fflush( stderr ); 25 } 26 27 if(breakOnError) 28 { 29 static volatile int* p = 0; 30 *p = 0; 31 } 32 throw exc; //拋出異常 33 }
總體而言,OpenCV中的錯誤處理機制,從C語言的處理方式轉變為C++中的處理方式.
具體的實現,請參考相應的源代碼.
參考資料:
