明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2323|回复: 14

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

  [复制链接]
发表于 2022-12-8 14:14 | 显示全部楼层 |阅读模式
本帖最后由 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++写的,速度最快。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

x

评分

参与人数 5明经币 +5 收起 理由
you_boss + 1
VBALISPER + 1
hhh454 + 1 很给力!学习了
masterlong + 1 赞一个!
自贡黄明儒 + 1 很给力!

查看全部评分

"觉得好,就打赏"
还没有人打赏,支持一下
发表于 2022-12-8 17:49 | 显示全部楼层
自贡黄明儒 发表于 2022-12-8 16:45
判断一下就行,只怕结果不同

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

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

点评

这个写法很简洁  发表于 2022-12-8 21:39

评分

参与人数 5明经币 +5 收起 理由
nyistjz + 1 赞一个!
VBALISPER + 1 很给力!
tigcat + 1 很给力!龙总总能给人惊喜
hhh454 + 1 学习了
自贡黄明儒 + 1 很给力!

查看全部评分

回复 支持 3 反对 0

使用道具 举报

发表于 2022-12-8 16:45 | 显示全部楼层
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 | 显示全部楼层
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 | 显示全部楼层
透彻!向大师学习!
发表于 2022-12-8 14:51 | 显示全部楼层
command和command-s对CAD版本有要求,比较讨厌。
发表于 2022-12-8 15:14 | 显示全部楼层
大佬太牛了
发表于 2022-12-8 15:34 | 显示全部楼层
厉害了,竟然从内存中深挖
发表于 2022-12-9 08:15 | 显示全部楼层
很有用,谢谢分享。
发表于 2022-12-9 09:58 | 显示全部楼层
佩服大佬的钻研精神
发表于 2022-12-19 20:07 | 显示全部楼层
如果能够根据不同版本编写一个自适应程序就好,暂时还没有思路
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-9 10:03 , Processed in 4.171552 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表