rt:
使用<setjmp.h>中的setjmp和longjmp(j,r)
他们2个函数的原理如下:
1.setjmp(j)设置“jump”点,用正确的程序上下文填充jmp_buf对象j。这个上下文包括程序存放位置、栈和框架指针,其它重要的寄存器和内存数据。当初始化完jump的上下文,setjmp()返回0值。
2. 以后调用longjmp(j,r)的效果就是一个非局部的goto或“长跳转”到由j描述的上下文处(也就是到那原来设置j的setjmp()处,这种情况下setjmp会又被调用了)。当作为长跳转的目标而被调用时,setjmp()返回r。(记住,setjmp()不能在这种情况时返回0。)
在c语言中德使用方法:
#include <setjmp.h>
int main(void) { jmp_buf j;
switch (setjmp(j)) {
case 0: printf("''setjmp'' is initializing ''j''\n"); raise_exception(); printf("this line should never appear\n"); case 1: printf("Case 1\n");break; case 2: printf("Case 2\n");break; case 3:
void raise_exception(void)
{
printf("exception raised\n");
longjmp(j, 1); /* jump to exception handler */
printf("this line should never appear\n");
}
在c++中定义如下:
#define INIT_EXCEPTION() (_gpExpData = (PEXCEPTION_DATA)malloc(sizeof(EXCEPTION_DATA)) , \
memset((void*)_gpExpData, \
0, \
sizeof(EXCEPTION_DATA)), \
_gpExpData->nIndex = -1)
#define TERM_EXCEPTION() free(_gpExpData)
#define TRY if(setjmp(_gpExpData->szJumps[++_gpExpData->nIndex]) == 0)
#define FI --(_gpExpData->nIndex)
#define CATCH(exp) else if(((exp) = _gpExpData->szpExceptions[_gpExpData->nIndex--]))
#define THROW(x) ( _gpExpData->szpExceptions[_gpExpData->nIndex] = new C_Exception x, \
longjmp(_gpExpData->szJumps[_gpExpData->nIndex], -1))
#define CLEAN(x) delete x
使用方法如下:
C_Exception *pexp;
TRY
{
m_pLower->DeviceSetDefaultSettings();
m_pLower->DeviceSetEepromFormat();
m_pLower->DeviceRetriveConfigurations(hconfig);
m_pLower->EDeviceValidateConfigurations();
FI;
}
CATCH(pexp)
{
pexp->PrintErrorMessage();
CLEAN(pexp);
NdisCloseConfiguration(hconfig);
THROW((ERR_STRING("*** Error in retriving configurations.\n")));
}
注意事项:1:首先执行TRY中的函数当里面的函数嗲用THROW时候,会longjmp,进而执行CATCH中的函数,
2:这种try-catch可以嵌套使用,但是最多嵌套255个(就是TRY里面的函数又有TRY-CATCH结构)
那么在java中那种, CATCH(ExceptionA){...}CATCH(ExceptionB){...}如何实现的呢,答案很简单,使用上面的switch结构
附录:
typedef struct _EXCEPTION_DATA
{
int nIndex;
jmp_buf szJumps[MAX_EXCEPTIONS];
C_Exception *szpExceptions[MAX_EXCEPTIONS];
} EXCEPTION_DATA, *PEXCEPTION_DATA;