baitang36 发表于 2022-12-8 14:14:19

[原创]从底层看command vl-cmdf command-s的区别

本帖最后由 baitang36 于 2022-12-8 14:27 编辑

首先,fas文件是不会调用command这个函数的,lsp中的command函数在编译时都被改成了保留函数ads-cmd
如果强制调用commad,会有什么结果呢?call_command.fas就是我的实验程序,加载它时会调用command,结果只是提示一句:错误: 无法应用特殊格式: COMMAND
从内存中挖出COMMAND的代码如下:
00000000: 14 01 00 00 01
00000005: 09 b4 02                         ;"VLMSG.DLL"
00000008: 33 34 76 00 00
00000013: 51 02 b3 02 01 00         ;string-resource
00000019: 09 d9 00                         ;"COMMAND"
00000022: 51 01 a0 01 01 00         ;al-intern
00000028: 51 02 e2 02 01 00         ;_msg-err
00000034: 16
写成lsp就是(_msg-err(string-resource "VLMSG.DLL" 30260 )(al-intern "COMMAND"))
确实是只显示一句错误信息。
再试验一下ads-cmd
命令: (load "c:/00/trf_9")
T
命令: (tranf "ads-cmd")
T
命令: !ads-cmd
#<SUBR @1749f438 ads-cmd>
命令: (ads-cmd)
*取消*
命令: (ads-cmd "line")
line 指定第一点: nil
指定第一点:
指定下一点或 [放弃(U)]:
ads-cmd这个函数可以没有参数或一个参数。lsp的一句comand会编译成多个ads-cmd
ads-com最终是调用acad.exe的acedcommand实现的。

再看一下vl-cmdf
挖出内存中的代码:
00000000: 14 01 00 00 01
00000005: 05 00
00000007: 51 01 f6 01 01 00         ;reslist->lresb
00000013: 51 01 05 01 01 00         ;ads-cmd-pure
00000019: 16
写成lsp就是(defun vl-cmdf (var0) (ads-cmd-pure (reslist->lresb var0)))
可以看出它调用了reslist->lresb和ads-cmd-pure这两个保留函数。
ads-cmd-pure是调用acad.exe的acedcmd来实现的。

command-s在64位的ACAD中是用c++来实现的,没有调用fas保留函数,它是调用accore.dll 中的acedcmdS实现的,函数名多了一个S

结论:
command是用fas保留函数实现的,并且由于多次调用ads-cmd函数,速度最慢。
vl-cmdf 是用fas保留函数实现的,用一个表一次输入所有参数,速度比command快。
command-s是直接用c++写的,速度最快。



llsheng_73 发表于 2022-12-8 17:49:33

自贡黄明儒 发表于 2022-12-8 16:45
判断一下就行,只怕结果不同

(if (>= (atoi (getvar "AcadVer")) 20)                          ;2015


((if command-s command-s vl-cmdf)"_.select" ss "")

自贡黄明儒 发表于 2022-12-8 16:45:03

rocking2008 发表于 2022-12-8 14:51
command和command-s对CAD版本有要求,比较讨厌。

判断一下就行,只怕结果不同

(if (>= (atoi (getvar "AcadVer")) 20)                          ;2015
    (command-s "_.select" ss "")
    (vl-cmdf "_.select" ss "")
)

自贡黄明儒 发表于 2022-12-28 11:21:10

llsheng_73 发表于 2022-12-8 17:49
((if command-s command-s vl-cmdf)"_.select" ss "")

08下
(defun ACET-CMD-EXIT ()
(while (/= "" (GETVAR "CMDNAMES"))
    ;;((if command-s command-s vl-cmdf) nil)
(command nil)
)
)
如果用(if command-s command-s vl-cmdf)代替(command nil),会出问题的。

紫苏炒黄瓜 发表于 2022-12-8 14:32:56

透彻!向大师学习!

rocking2008 发表于 2022-12-8 14:51:59

command和command-s对CAD版本有要求,比较讨厌。

magicheno 发表于 2022-12-8 15:14:47

大佬太牛了

gdfyhao 发表于 2022-12-8 15:34:36

厉害了,竟然从内存中深挖

VBALISPER 发表于 2022-12-9 08:15:34

很有用,谢谢分享。

xpzzj 发表于 2022-12-9 09:58:34

佩服大佬的钻研精神

我爱lisp 发表于 2022-12-19 20:07:41

如果能够根据不同版本编写一个自适应程序就好,暂时还没有思路
页: [1] 2
查看完整版本: [原创]从底层看command vl-cmdf command-s的区别