Handling Automation errors in Visual LISPhtml
翻譯自原文Kean's blog:http://through-the-interface.typepad.com/through_the_interface/2006/08/handling_automa.htmlapp
自從VLisp被推廣,開發者便利用它的能力優點來引用COM自動化接口。這種使LISP平臺增長許多新的擴展的功能,就像你能經過召喚ObjectARX 程序來實現定義LISP函數。可是,自動操做LISP 容許開發者經過其餘應用程序決定於COM的API,就像Miscrosoft Excle。ide
在LISP中快速標註錯誤處理...函數
傳統作法是在LISP中定義erro函數,來在執行的過程當中抓住錯誤。經過這個函數,他們能夠常常報errno 的值-Autocad 使用它來告訴LISP應用程序哪一種錯誤正在發生,這樣可使開發者明確問題的原因。spa
這很好,可是這種全局錯誤抓取使錯誤以後不容易恢復程序。 翻譯
當經過自動操做接口來處理,事情會變得不一樣。自動處理客戶端一半須要當錯誤發生時抓住它,而不是定義全局錯誤處理函數。VLisp經過一個叫vl-catch-all-apply的函數來實現的。vl-catch-all-apply是這樣一個函數,不一樣函數引用時,他的函數名被做爲內容提要並以列表的方式發送給vl-catch-all-apply函數。vl-catch-all-apply在函數被引用時,盡全力去抓取錯誤。apply與vl-catch-all-apply的區別就是函數的返回值,既不是函數引用的返回值,也不是錯誤對象。htm
舉個不包含自動處理的例子,下面使用我最喜歡的代碼要求用戶輸入兩個數字作除法,並反饋結果。咱們用(vl-catch-all-error-p)看結果是否正確,若是不正確,咱們用(vl-catch-all-error-message)看錯誤信息。對象
(defun c:div (/ first second result)blog
(setq first (getreal "\nEnter the first number: ")接口
second (getreal "\nEnter the second number: ")
result (vl-catch-all-apply '/ (list first second))
)
(if (vl-catch-all-error-p result)
(princ (strcat "\nCaught an exception: "
(vl-catch-all-error-message result)
)
)
(princ (strcat "\nSuccess - the result is "
(rtos result)
)
)
)
(princ)
)
當你運行程序時,獲得如下結果
Command: div
Enter the first number: 50
Enter the second number: 2
Success - the result is 25.0000
Command: div
Enter the first number: 50
Enter the second number: 0
Caught an exception: divide by zero
因此,如何把這個技術應用在自動引用上呢?讓咱們看另外一段代碼,此次引用一個函數來檢查兩個立體的衝突,代碼定義了名爲CHECKINT的命令,請求選擇兩個立體。假設兩個立體已經選擇,它會引用CheckInterference Automation方法,指定任何交集應被建立爲獨立的實體。
; Helper function to check whether an entity is a solid
(defun is-solid-p (ename)
(= (cdr (assoc 0 (entget ename))) "3DSOLID")
)
; The CHECKINT command
(defun c:checkint (/ first second e1 e2 result)
(vl-load-com)
(setq first (entsel "\nSelect the first solid: ")
second (entsel "\nSelect the second solid: ")
)
(if (and first
second
(is-solid-p (setq e1 (car first)))
(is-solid-p (setq e2 (car second)))
)
(progn
(setq result (vl-catch-all-apply
'vla-CheckInterference
(list (vlax-ename->vla-object e1)
(vlax-ename->vla-object e2)
:vlax-true
)
)
)
(if (vl-catch-all-error-p result)
(princ (strcat "\nCaught an exception: "
(vl-catch-all-error-message result)
)
)
(progn
(princ "\nSuccess!")
; Highlight the newly created intersection solid
(vla-Highlight result :vlax-true)
(vlax-release-object result)
)
)
)
(princ "\nMust select two solids.")
)
(princ)
)