設(shè)為首頁收藏本站Access中國

Office中國論壇/Access中國論壇

 找回密碼
 注冊

QQ登錄

只需一步,快速開始

tag 標(biāo)簽: finally機制

相關(guān)帖子

版塊 作者 回復(fù)/查看 最后發(fā)表

沒有相關(guān)內(nèi)容

相關(guān)日志

分享 不太好懂的try catch finally?
熱度 1 ganlinlao 2016-10-13 10:44
眾所周知,F(xiàn)reebasic和VBA一樣也是使用On errror方式進行錯誤處理的,沒有在語法上實現(xiàn)try catch finally的錯誤處理機制。那么如何自己實現(xiàn)Try catch finally呢,使用下面這個exceptions.bi的宏文件。 源代碼如下: #Ifndef EXCEPTION_RECORD #Error Please include windows.bi first! #EndIf #Ifndef __FB_WIN32__ #Error Operating system not supported! #EndIf #Macro __trycheck(_name_) #Ifndef __eh_##_name_##_try_set #Error Undefined Try block name: _name_ #EndIf #EndMacro #Macro Try (_name_) #Ifdef __eh_##_name_##_try_set2 #Error Duplicated definition: _name_ #EndIf #Define __eh_##_name_##_try_set #Define __eh_##_name_##_try_set2 Scope Dim As Byte __eh_##_name_##_doret = 0 Dim As Any Ptr __eh_##_name_##_ehesp = 0 Dim As Byte __eh_##_name_##_ehandled = 0 Dim As Byte __eh_##_name_##_wasincatch = 0 Dim As EXCEPTION_RECORD Ptr __eh_##_name_##_erec = 0 Dim As Byte __eh_##_name_##_erecarr(SizeOf(EXCEPTION_RECORD)) Dim As Byte __eh_##_name_##_econarr(SizeOf(CONTEXT)) Asm __eh_##_name_##_try: pushad mov esi, offset __eh_##_name_##_except push esi push dword ptr fs: mov dword ptr fs: , esp End Asm Scope #EndMacro #Macro __catch_codestart(_name_) End Scope #Define __eh_##_name_##_except_set Asm jmp __eh_##_name_##_finally_continue __eh_##_name_##_except: mov eax, mov eax, cmp eax, 2 jne __eh_##_name_##_nounwind mov byte ptr , 1 call __eh_##_name_##_finally mov eax, 1 ret __eh_##_name_##_nounwind: mov eax, esp mov esp, pop dword ptr fs: mov , eax add esp, 4 popad mov eax, mov , eax mov edx, eax End Asm Scope Dim As EXCEPTION_RECORD Ptr ERecord Dim As CONTEXT Ptr EContext #Define ECode (ERecord-ExceptionCode) #Define EAddress (ERecord-ExceptionAddress) #Define ENumParams (ERecord-NumberParameters) #Define EParamsPtr CPtr(Integer Ptr, (@ERecord-ExceptionInformation(0))) Asm push edx mov edx, mov , edx pop edx mov edx, mov , edx End Asm #Define __ersize (SizeOf(EXCEPTION_RECORD) + ERecord-NumberParameters * 4 - 4) #Define __erarrsize (UBound(__eh_##_name_##_erecarr) + 1) CopyMemory(Cast(Any Ptr, @__eh_##_name_##_erecarr(0)), Cast(Any Ptr, ERecord), IIf(__ersize = __erarrsize, __ersize, __erarrsize)) #Undef __erarrsize #Undef __ersize ERecord = Cast(EXCEPTION_RECORD Ptr, @__eh_##_name_##_erecarr(0)) __eh_##_name_##_erec = ERecord CopyMemory(Cast(Any Ptr, @__eh_##_name_##_econarr(0)), Cast(Any Ptr, EContext), UBound(__eh_##_name_##_econarr) + 1) EContext = Cast(CONTEXT Ptr, @__eh_##_name_##_econarr(0)) Select Case ECode #EndMacro #Define EParams(_i_) IIf(EParamsPtr 0 AndAlso _i_ ENumParams, (EParamsPtr) , 0) #Macro __catch_next(_name_, _ecode_) #Define __ , Case _ecode_ #Undef __ Asm mov byte ptr , 1 Asm mov byte ptr , 1 #EndMacro #Macro Catch (_name_, _ecode_) __trycheck(_name_) #Ifdef __eh_##_name_##_finally_set #Error Using Catch after Finally not allowed! #EndIf #Ifndef __eh_##_name_##_except_set __catch_codestart(_name_) #EndIf __catch_next(_name_, _ecode_) #EndMacro #Macro Finally (_name_) #Ifdef __eh_##_name_##_finally_set #Error Multiple Finally statements not allowed! #EndIf __trycheck(_name_) #Ifndef __eh_##_name_##_except_set Catch (_name_, 0) __eh_##_name_##_ehandled = 0 #EndIf End Select End Scope #Define __eh_##_name_##_finally_set Asm mov byte ptr , 0 __eh_##_name_##_finally: End Asm Scope Select Case 0 Case 0 #EndMacro #Macro Leave(_name_) __trycheck(_name_) Asm mov byte ptr , 1 call __eh_##_name_##_finally End Asm #EndMacro #Macro EndTry(_name_) __trycheck(_name_) #Ifndef __eh_##_name_##_except_set Catch (_name_, 0) __eh_##_name_##_ehandled = 0 #EndIf #Ifndef __eh_##_name_##_finally_set Finally (_name_) #EndIf End Select End Scope Asm cmp byte ptr , 0 je __eh_##_name_##_noret ret __eh_##_name_##_noret: cmp byte ptr , 0 jne __eh_##_name_##_continue mov esp, End Asm RaiseException(__eh_##_name_##_erec-ExceptionCode, __eh_##_name_##_erec-ExceptionFlags, __eh_##_name_##_erec-NumberParameters, @__eh_##_name_##_erec-ExceptionInformation(0)) Asm int3 __eh_##_name_##_finally_continue: mov byte ptr , 1 call __eh_##_name_##_finally pop dword ptr fs: add esp, 36 jmp __eh_##_name_##_end_try __eh_##_name_##_continue: cmp byte ptr , 1 je __eh_##_name_##_end_try pop dword ptr fs: add esp, 36 __eh_##_name_##_end_try: End Asm End Scope #Undef __eh_##_name_##_try_set #EndMacro #Macro ExitTry(_name_) __trycheck(_name_) Leave(_name_) Asm jmp __eh_##_name_##_end_try #EndMacro #Macro RaiseParam(_ecode_, _nump_, _params_) Scope #Define __ , Dim __params(_nump_ - 1) As Integer = {_params_} #Undef __ RaiseException(_ecode_, 0, _nump_, @__params(0)) End Scope #EndMacro #Macro Raise(_ecode_) RaiseException(_ecode_, 0, 0, 0) #EndMacro 這個其實不好理解。有時間再繼續(xù)深入了解一下。
個人分類: FreeBasic|2487 次閱讀|1 個評論

QQ|站長郵箱|小黑屋|手機版|Office中國/Access中國 ( 粵ICP備10043721號-1 )  

GMT+8, 2024-10-23 08:25 , Processed in 0.064157 second(s), 13 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

返回頂部