Ich habe einen Try/Catch Errorhandler geschreiben, dieser Funktioniert unter Windows und Linux bei 32 und 64 Bit.
Code: Alles auswählen
;****************************
;*** Try/Catch Commands ***
;****************************
;*** (c) 2009 RocketRider ***
;*** RocketRider.eu ***
;****************************
;*** PureBasic 4.31 ***
;****************************
;+ Supports Windows/Linux 32/64 Bit
;+ Does not support multi threated applications at this time
DisableDebugger
Global __TRYCATCH_pOnErrorAddress.i
Global __TRYCATCH_pOldOnErrorAddress.i
Global __TRYCATCH_pTryCatchStackPointer.i
Global __TRYCATCH_pOldTryCatchStackPointer.i
__TRYCATCH_pOnErrorAddress = ?__TRYCATCH_DefaultExceptionHandler
OnErrorGoto(?__TRYCATCH_DefaultExceptionHandler)
Goto __TRYCATCH_EndDefaultExceptionHandler
__TRYCATCH_DefaultExceptionHandler:
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
MessageRequester("Unhandled Exception!", ErrorMessage(), #MB_ICONERROR)
CompilerElse
MessageRequester("Unhandled Exception!", ErrorMessage())
CompilerEndIf
End
__TRYCATCH_EndDefaultExceptionHandler:
Macro Try(Name)
__TRYCATCH_pOldOnErrorAddress = __TRYCATCH_pOnErrorAddress
__TRYCATCH_pOldTryCatchStackPointer = __TRYCATCH_pTryCatchStackPointer
__TRYCATCH_pOnErrorAddress = ?__TRYCATCH_#Name
CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
!MOV dword[v___TRYCATCH_pTryCatchStackPointer],ESP
CompilerElse
CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
!MOV qword[v___TRYCATCH_pTryCatchStackPointer],RSP
CompilerElse
CompilerError "Processor not supported by try/catch handler"
CompilerEndIf
CompilerEndIf
OnErrorGoto(?__TRYCATCH_#Name)
EndMacro
Macro Catch(Name)
Goto __TRYCATCH_End#Name
__TRYCATCH_#Name:
CompilerIf #PB_Compiler_Processor =#PB_Processor_x86
!MOV ESP,dword[v___TRYCATCH_pTryCatchStackPointer]
CompilerElse
CompilerIf #PB_Compiler_Processor =#PB_Processor_x64
!MOV RSP,qword[v___TRYCATCH_pTryCatchStackPointer]
CompilerElse
CompilerError "Processor not supported by try/catch handler"
CompilerEndIf
CompilerEndIf
__TRYCATCH_pTryCatchStackPointer = __TRYCATCH_pOldTryCatchStackPointer
__TRYCATCH_pOnErrorAddress = __TRYCATCH_pOldOnErrorAddress
OnErrorGoto(__TRYCATCH_pOnErrorAddress)
EndMacro
Macro EndCatch(Name)
__TRYCATCH_End#Name:
__TRYCATCH_pTryCatchStackPointer = __TRYCATCH_pOldTryCatchStackPointer
If __TRYCATCH_pOnErrorAddress <> __TRYCATCH_pOldOnErrorAddress
__TRYCATCH_pOnErrorAddress = __TRYCATCH_pOldOnErrorAddress
OnErrorGoto(__TRYCATCH_pOnErrorAddress)
EndIf
EndMacro
;Test exception handling
Try(INTERRUPT_TEST) ; Use Try to begin the exeption handling. INTERRUPT_TEST is the name of the try/catch section. It can be anything, but must be unique.
;Programcode which causes an exception
!int 21h
Catch(INTERRUPT_TEST) ; continues execution after Catch(...) if an exception occured, or jumps directly to EndCatch(...) if no exception occured.
;This part will be only called if an exception was raised.
MessageRequester("Exception found!", ErrorMessage())
EndCatch(INTERRUPT_TEST) ; end try/catch section
;The stack will be corrected and the program can be continued.
; Now a second test...
Procedure Test()
bResult = #True
Try(POKEL_TEST)
;Cause an exception
PokeL(0,0)
Catch(POKEL_TEST)
;This part will be only called if an exception was raised.
MessageRequester("Exception found in Procedure Test()!", ErrorMessage())
;Do not use ProcedureReturn into a Catch...EndCatch section, because exeption handle would not work correct, if nested try-blocks are used (EndCatch would be not called in this case).
;Instead st return value
bResult = #False
EndCatch(POKEL_TEST)
ProcedureReturn bResult
EndProcedure
MessageRequester("Result", Str(Test()))
RocketRider