简介:这份资料面向AutoCAD二次开发的学习者与工程技术人员,围绕VLISP、VBA、ARX三条技术路线,解决从脚本自动化到C++插件开发的入门与查阅需求。压缩包共21个文件、约17.57MB,以chm帮助文档、pdf函数库查询辞典、doc光盘使用指导为主,辅以cpp、def、arx、lib等ARX工程源码与编译产物,以及dsw、dsp等旧版工程配置,便于对照查阅函数用法并动手编译示例。内容覆盖VLISP语法与函数库、VBA宏与属性事件、ARX项目搭建与调试,并配有示例代码与练习素材,适合边查边练、按模块检索。已有337人学习下载,可作为案头工具书式的参考资料,帮助读者快速定位接口说明、理解开发流程并积累可复用的代码片段。
1. 拿到一份 AutoCAD 二次开发案头书,先别急着翻代码
如果你手上正躺着一份名为「AutoCAD 开发案头书 vlisp vba arx」的资料包,第一反应大概率是:三种语言混在一起,到底从哪看起?这恰恰是它最有价值的地方——AutoLISP、VBA、ARX 不是三个并列的入门选项,而是 AutoCAD 二次开发从轻到重的三条技术路线,分别对应「快速改图」「表单化批处理」「深度集成」三类真实诉求。案头书的价值不在于教你背函数,而在于让你在动手前就知道:什么活该用 LISP 十分钟搞定,什么活必须上 ARX 才不翻车。适合已经会用 CAD 画图、但被重复劳动折磨的从业者,也适合接过别人半截插件、需要读懂再改的维护者。
2. 三条技术路线怎么选:LISP、VBA、ARX 的边界与代价
选型这件事,翻车最多的不是不会写,而是一开始就选错了工具。见过太多人拿 VBA 去写需要毫秒级响应的图形遍历,也见过用 LISP 硬扛需要调用外部 DLL 的复杂计算,最后都卡在性能和部署上。这一章先把三条路线的能力边界、运行机制和代价讲清楚,再落到具体怎么起手。
2.1 三条路线的运行机制差异
AutoLISP 是解释执行的,代码以文本形式随图纸或独立文件加载,改一行存盘就能重跑,不需要编译。它跑在 AutoCAD 进程内,能直接读写图元数据、调用命令、操作选择集,缺点是纯解释、循环里做大量字符串拼接会明显变慢,而且对内存和外部接口的支持有限。
VBA 走的是 COM 自动化,通过 ActiveX 对象模型访问 AutoCAD。它的优势是窗体、控件、事件这些交互能力现成,适合做带界面的批处理工具;代价是依赖 COM 注册,跨版本兼容性差,64 位环境下的部署经常出问题,而且微软对 VBA 的长期支持态度一直不算积极。
ARX 是 C++ 编写的原生扩展,编译成 DLL 后由 AutoCAD 直接加载,运行在进程内且能访问底层数据库和自定义实体。性能最好、能力最深,但开发门槛和调试成本也最高,一次崩溃可能直接带走整个 CAD 进程,血泪经验是:ARX 里任何指针和事务管理出错,现场都很难复现。
| 路线 | 执行方式 | 典型场景 | 主要代价 |
|---|---|---|---|
| AutoLISP | 解释执行 | 批量改属性、快速绘图命令、图纸规整 | 大数据量循环慢,外部接口弱 |
| VBA | COM 自动化 | 带窗体的批处理、Excel 联动报表 | 注册依赖、跨版本兼容差 |
| ARX | 原生 DLL | 自定义实体、高性能图形遍历、深度集成 | 编译调试成本高,崩溃影响大 |
2.2 按任务规模做选型判断
判断标准可以简化成三个问题:数据量多大、要不要界面、要不要碰底层。改几十张图的图层和文字,LISP 足够;要弹窗让用户选参数、再把结果导出成表格,VBA 更省事;要遍历上万图元做几何计算、或者定义一种 CAD 原生不认识的对象,才轮到 ARX。
一个常见的误用是拿 LISP 写需要频繁访问外部数据库的工具,结果每次查询都阻塞主线程,用户以为 CAD 卡死了。反过来,用 ARX 写一个只改图层颜色的命令,属于杀鸡用牛刀,编译部署的麻烦远超收益。我一般的习惯是:先用 LISP 写出能跑的原型验证逻辑,确认需求稳定、性能不够时再考虑往 VBA 或 ARX 迁移,而不是一上来就选最重的。
2.3 环境准备与第一个可运行命令
不管走哪条路线,起手都要确认两件事:CAD 的受信任路径设置,以及开发文件的加载方式。LISP 文件放在受信任目录下才能免提示加载,这一点新手最容易忽略。
;; 最小可运行示例:统计当前选择集中直线数量 (defun c:CountLines ( / ss i n ent) (setq ss (ssget '((0 . "LINE")))) ; 只选直线图元 (if ss (progn (setq n (sslength ss) i 0) (while (< i n) (setq ent (ssname ss i)) ; 逐个取图元名 (setq i (1+ i)) ) (princ (strcat "\n共选中 " (itoa n) " 条直线")) ) (princ "\n未选中任何直线") ) (princ) )这段代码的逻辑很直白:ssget用过滤表'((0 . "LINE"))只抓直线,sslength拿数量,while循环遍历只是为了演示取图元的方式,实际统计数量不需要循环。参数上,过滤表的组码0表示图元类型,改成"CIRCLE"就是统计圆。(princ)结尾是为了让命令干净退出,不加的话命令行会回显返回值,属于小细节但影响体验。
加载方式有两种:在命令行输入APPLOAD手动选文件,或者把文件放进受信任路径后每次自动加载。调试阶段建议用前者,改完存盘重新APPLOAD即可,不用重启 CAD。
3. VBA 与 ARX 的落地:从窗体工具到原生扩展
LISP 能覆盖大部分日常需求,但一旦涉及界面交互或高性能计算,就得往 VBA 和 ARX 走。这一章分别给出两条路线的可执行起手步骤,重点放在「怎么让第一个程序跑起来」和「参数怎么设」,而不是罗列对象模型。
3.1 VBA 窗体工具的搭建步骤
VBA 的入口是VBAIDE命令,打开后新建一个窗体,拖控件、写事件。一个典型的批处理工具结构是:窗体收集参数,模块里的过程遍历图纸执行操作。下面是一个把选中文字统一改高的最小示例。
' 在标准模块中:把选中文字的字高统一设为指定值 Public Sub SetTextHeight() Dim ss As AcadSelectionSet Dim filterType(0) As Integer Dim filterData(0) As Variant Dim i As Integer Dim newH As Double newH = 2.5 ' 目标字高,按图纸单位调整 On Error Resume Next ThisDrawing.SelectionSets.Item("TXTSS").Delete ' 先清掉同名选择集 On Error GoTo 0 Set ss = ThisDrawing.SelectionSets.Add("TXTSS") filterType(0) = 0 filterData(0) = "TEXT" ' 只处理单行文字 ss.SelectOnScreen filterType, filterData For i = 0 To ss.Count - 1 ss.Item(i).Height = newH ' 逐个改字高 Next i ss.Delete End Sub逻辑说明:SelectionSets是 COM 里的选择集对象,必须先删同名再新建,否则重复运行会报错,这是 VBA 里最常见的翻车点之一。SelectOnScreen让用户在图上框选,过滤数组filterType/filterData的用法和 LISP 的过滤表思路一致,只是换成了 COM 的数组形式。参数newH直接决定结果,实际工具里应该从窗体文本框读取并做数值校验,避免用户输入非数字导致类型错误。
部署时要注意:VBA 工程通常嵌在.dvb文件里,通过VBALOAD加载、VBARUN运行。跨机器分发时,如果目标机器没装 VBA 模块或位数不匹配,加载会失败,这是 VBA 路线绕不开的兼容性代价。
3.2 ARX 工程的编译与加载链路
ARX 的起手比前两者重,需要一套 C++ 编译环境和对应版本的 ObjectARX SDK。工程配置的关键是头文件路径、库路径和输出后缀,任何一项对不上,编译能过但加载会失败。
// 最小 ARX 命令:在命令行输出当前图形实体总数 #include "aced.h" #include "dbents.h" void CountEntities() { AcDbBlockTable *pBlkTab = nullptr; AcDbBlockTableRecord *pModelSpace = nullptr; AcDbBlockTableRecordIterator *pIter = nullptr; int count = 0; acdbHostApplicationServices()->workingDatabase() ->getBlockTable(pBlkTab, AcDb::kForRead); // 只读打开块表 pBlkTab->getAt(ACDB_MODEL_SPACE, pModelSpace, AcDb::kForRead); pModelSpace->newIterator(pIter); // 遍历模型空间 for (; !pIter->done(); pIter->step()) { count++; } delete pIter; pModelSpace->close(); pBlkTab->close(); // 必须成对关闭 acutPrintf(_T("\n模型空间实体数: %d"), count); } extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt) { switch (msg) { case AcRx::kInitAppMsg: acrxRegisterCommand(_T("COUNTENTS"), CountEntities); // 注册命令名 break; case AcRx::kUnloadAppMsg: break; } return AcRx::kRetOK; }这段代码的重点不在统计,而在资源管理:getBlockTable、getAt、newIterator打开的每个对象都必须close或delete,漏一个就会造成数据库锁未释放,表现为后续命令莫名失败。acrxEntryPoint是 ARX 的入口,kInitAppMsg时注册命令,命令名COUNTENTS就是用户在命令行敲的。编译产物是.arx文件,用APPLOAD加载,加载失败时先看位数和 SDK 版本是否与 CAD 匹配,这是排查的第一顺位。
3.3 三种语言之间的协作方式
实际项目里三者经常混用:LISP 做轻量命令和菜单入口,VBA 做参数窗体,ARX 做重计算,彼此通过命令调用或 COM 接口衔接。比如 LISP 里可以用(command "VBARUN" "模块.过程")触发 VBA 宏,ARX 注册的命令也能被 LISP 的command直接调用。协作的关键是约定好命令名和数据传递方式,别让一个工具同时依赖三套加载顺序,否则部署时很难说清到底哪一环没起来。
4. 避坑与排查:加载失败、版本错配与性能陷阱
这一章集中处理实操里最常撞上的几类问题,每条按现象、原因、解决三段写,都是能直接对照排查的。
现象:LISP 文件每次打开图纸都提示加载,点允许后命令仍找不到。原因多半是文件不在受信任路径,或者defun里的命令名拼写和调用不一致。解决是把文件放进「选项 → 文件 → 受信任的位置」列表,再用APPLOAD的启动组挂载;命令找不到时先在命令行敲(c:命令名)看是否报未定义,确认加载成功再查拼写。
现象:VBA 宏在开发机正常,换一台机器加载报错。原因是 COM 注册缺失或 Office/CAD 位数不匹配,.dvb依赖的运行库在目标机不存在。解决是确认目标机 CAD 位数与 VBA 环境一致,必要时改用早期绑定为后期绑定,减少对类型库的硬依赖;分发前在干净环境里完整走一遍加载流程。
现象:ARX 加载时提示「无法找到程序入口」或直接导致 CAD 退出。原因是 SDK 版本与 CAD 版本不匹配,或编译位数错误,也可能是入口函数签名不对。解决是对照 CAD 版本选对应 ObjectARX SDK,确认工程输出为对应位数,检查acrxEntryPoint的签名和导出设置;崩溃类问题先用最小空工程验证加载链路,再逐步加代码定位。
现象:LISP 循环处理上万图元时 CAD 明显卡顿甚至无响应。原因是解释执行下频繁调用ssname、字符串拼接和command调用开销大。解决是尽量用ssget过滤缩小集合、把command调用换成直接改图元数据、循环内避免反复strcat;数据量确实大时考虑迁到 ARX,而不是在 LISP 里硬优化。
现象:同一份代码在别人机器上结果不对,自己机器正常。原因常是系统变量或图纸单位不同,比如OSMODE、INSUNITS影响捕捉和单位换算。解决是在命令开头保存关键系统变量、结束时恢复,涉及单位的计算显式读取图纸单位再换算,别假设默认值。
提示:排查顺序建议固定为「加载是否成功 → 命令是否注册 → 数据是否取到 → 结果是否正确」,从前往后逐段验证,比一上来就怀疑算法高效得多。
5. 把案头书用成自己的工具箱:版本对照与回归验证
案头书这类资料最容易犯的错是「看懂了但没跑通」,因为三种语言各自依赖不同的版本环境,书上的示例在你这台机器上未必能直接加载。我的做法是先建一张版本对照表,把 CAD 版本、SDK 版本、VBA 环境、LISP 加载方式四列对齐,任何一次环境变动都先查这张表,而不是凭记忆试。
| 项目 | 需要确认的内容 | 常见错配表现 |
|---|---|---|
| CAD 版本 | 主版本号与位数 | ARX 加载即崩 |
| ObjectARX SDK | 与 CAD 主版本严格对应 | 编译过、加载失败 |
| VBA 环境 | 是否安装、位数一致 | 宏无法运行 |
| LISP 加载 | 受信任路径、启动组 | 每次提示加载 |
验证方法上,我习惯给每个工具留一个「冒烟命令」:LISP 工具留一个只打印版本号的命令,VBA 留一个只弹空窗体的宏,ARX 留一个只输出一行文字的命令。每次换环境或改代码,先跑冒烟命令确认加载链路通,再跑完整逻辑。这个习惯救过很多次——有回一个 ARX 工具在客户现场加载后 CAD 直接退出,靠冒烟命令五分钟就定位到是 SDK 版本错配,而不是代码逻辑问题。
另一个具体技巧是把案头书里的示例按「最小可运行」原则拆开重写一遍,而不是整段复制。书上的代码往往为了演示完整性省略了错误处理,直接拿来用会在边界情况翻车。拆写的过程中顺手把参数含义、依赖的系统变量、失败时的表现记在注释里,这份注释比原书更贴合你自己的环境。从那以后我每次接手一份新的开发资料,都强制先跑通一个最小命令再往下读,希望帮到你。
本文还有配套的精品资源,点击获取