关于 lambda
本帖最后由 baitang36 于 2022-3-19 21:53 编辑自动桌子的帮助文件中说lambda的作用是定义一个无名函数。它相当于现定义现调用的函数,因为无名,没法在别的地方调用。
这个无名是如何实现的呢?
分析fas文件,发现它和有名的一般函数没啥区别,只不过是所有的lambda都用了一个函数名-lambda-
做如下试验:
(defun t1(fun1 str1)
(fun1 str1)
)
(defun t2()
(t1
(lambda (x)(t1 princ x))"t1234")
)
把这个小程序编译一下,用fas61.exe解码,16进制编辑器中显示:
Offset 01234567 89 10 11 12 13 14 15
00000000 0D 0A 20 46 41 53 34 2D46 49 4C 45 20 3B 20 44 FAS4-FILE ; D
00000016 6F 20 6E 6F 74 20 63 6861 6E 67 65 20 69 74 21 o not change it!
00000032 0D 0A 38 33 0D 0A 38 2024 14 02 02 02 00 09 06 838 $
00000048 00 5C 00 00 09 05 00 5C01 00 18 05 00 03 05 00 \ \
00000064 35 01 06 00 03 19 02 0016 14 00 00 00 00 57 1D 5 W
00000080 00 00 00 14 01 01 01 0009 04 00 5C 00 00 18 03 \
00000096 00 03 03 00 03 04 00 3502 02 00 03 19 01 00 16 5
00000112 09 07 00 09 01 00 35 0202 00 03 16 24 0D 0A 31 5 $1
00000128 37 34 20 36 20 24 14 0101 01 00 32 00 32 27 2A 74 6 $ 2 2'*
00000144 39 01 00 5B 54 32 00 5431 00 00 01 01 43 00 00 9[T2 T1 C
00000160 04 00 0A 32 2A 32 47 2A32 20 32 53 2A 32 00 32 2*2G*2 2S*2 2
00000176 20 2A 39 03 00 55 01 0005 00 74 31 32 33 34 5B *9U t1234[
00000192 54 31 00 50 52 49 4E 4300 58 00 53 54 52 31 00 T1 PRINC X STR1
00000208 46 55 4E 31 00 00 5C 0000 32 2A 5B 2D 6C 61 6D FUN1\2*[-lam
00000224 62 64 61 2D 00 00 3A 5C00 00 43 00 00 08 00 0A bda-:\C
00000240 5C 00 00 32 20 5B 54 3200 00 3A 5C 00 00 32 00 \2 [T2:\2
00000256 5B 54 31 00 00 3A 01 4304 00 02 00 1C 14 01 00 [T1: C
00000272 00 00 09 03 00 0A 57 0000 00 00 09 05 00 06 02 W
00000288 00 09 02 00 0A 57 00 0000 00 09 04 00 06 01 00 W
00000304 09 01 00 16 17 00 AE B2B6 33 E2 E3 22 0A 3B 66 ?忏" ;f
00000320 61 73 34 20 63 72 75 6E63 68 0A 3B 24 3B 41 33 as4 crunch ;$;A3
00000336 2F 31 39 2F 32 32 /19/22
可以看到定义了一个函数-lambda-,它的代码开始地址是2A,就是红色代码部分。
把这个-lambda-改成Glambda-,然后反编译试试。
(DEFUN T1( FUN1 STR1 ) (FUN1 STR1 ))
(DEFUN T2() (DEFUN Glambda-( X ) (T1 PRINC X )) (T1 'Glambda- "t1234" ))
可以看出,这和普通的函数没啥区别,只是发生了一个小错误,Glambda-前面多了一个单引号,导致执行时出错。看来反编译程序不完善,存在bug。
附件中是试验文件,感兴趣的朋友可以下载研究。
;Set global width for all polylines in the drawing,
;including blocks and nested blocks
;Stefan M.
;v1.01 - 25.07.2018
(defun C:gw ( / *error* acdoc)
(vl-load-com)
(setq acdoc (vla-get-activedocument (vlax-get-acad-object)))
(if (= (logand 8 (getvar 'undoctl)) 8) (vla-endundomark acdoc))
(vla-startundomark acdoc)
(defun *error* (msg)
(and msg
(not (wcmatch (strcase msg) "*EXIT*,*QUIT*,*CANCEL*,*BREAK*"))
(princ (strcat "\nError: " msg))
)
(if (= (logand 8 (getvar 'undoctl)) 8) (vla-endundomark acdoc))
(princ)
)
(if
(setq *wd*
(cond
((progn
(initget 4)
(getdist (strcat "\nSpecify Global Width <" (if *wd* (rtos *wd*) "") ">: "))
)
)
(*wd*)
)
)
(vlax-for bl (vla-get-blocks acdoc)
(if
(eq (vla-get-isxref bl) :vlax-false)
(vlax-for obj bl
(if
(eq (vla-get-objectname obj) "AcDbPolyline")
(vl-catch-all-apply 'vla-put-constantwidth (list obj *wd*))
)
)
)
)
)
(vla-regen acdoc acactiveviewport)
(*error* nil)
(princ)
) (defun c:tbg ( / col )
(if tbg:flg
(setq col 16777215 tbg:flg nil)
(setq col 0 tbg:flgt )
)
(foreach prp '(graphicswinmodelbackgrndcolor modelcrosshaircolor)
(vlax-put-property (acdisp) prp (setq col (- 16777215 col)))
)
(princ)
)
(defun acdisp nil
(eval
(list 'defun 'acdisp 'nil
(vla-get-display (vla-get-preferences (vlax-get-acad-object)))
)
)
(acdisp)
)
(vl-load-com) (princ) 本帖最后由 不死猫 于 2022-3-19 09:28 编辑
系统编译得到的是小写的,用户定义是大写的,自己写defun -lambad-编译后改成小写的也可以让反编译失效 顶起来 研究的好深 研究的好深。。。。看不懂。 我只轻轻的路过一下:lol 感谢大佬知识共享! 学无止境,向楼主学习 有学问就是好。
页:
[1]
2