明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 17493|回复: 37

[分享]如何在ARX、LISP和VBA之间选择?(英文资料,附带翻译的中文资料)

  [复制链接]
发表于 2004-12-25 23:40:00 | 显示全部楼层 |阅读模式
The AutoCAD API's When and Why
Written by Andrew Canfield
There are three major API's with which you can extend AutoCAD. They are respectively: a C/C++ api called objectARX, a VB/VBA api, and an AutoLisp/VisualLisp api. Every developer has their favorite but all partiality aside people often wonder which is better, which should I use? The answer to those questions is: "It depends on what you need to accomplish". Each API has different things, which make it better in given situations. When deciding on which API to use there are 4 things you need to ask yourself. What language am I most comfortable in? How much time do I have? Who is the target user and how much AutoCAD experience do they have? How much control over AutoCAD and possibly Windows do I need to accomplish the task quickly? After I address some of the functionality of the different API's you will see why these are relevant. I am only going to deal with these API's as they apply internally to AutoCAD not as stand alone applications.

--------------------------------------------------------------------------------
The objectARX API:
Out of the three API's this one has the most control over AutoCAD and Windows. You can register its commands with AutoCAD. The user needs to know very little about AutoCAD to run your program. The drawbacks to it are it takes longer to develop in it for most developers than VBA or Lisp, and often it is overkill especially for simple drafting tools. To get anything done in this API you should already be very familiar with C and C++. On a personal level this API is my favorite but that is because I do 99% of all my development in C and C++ so when I do something for AutoCAD it's easier for me not to have to switch languages. For me it falls into the category of "what language am I most comfortable with?". There are things within AutoCAD that this API can access that the other API's cannot. This is the major reason for most developers who use this API. They need to do something and it literally cannot be done using the other two API's. This is also the only API to which you can secure your code from having others read and copy your source. If you need to develop custom objects, work with spatial filtering, expose functionality to an application using another API, are developing third party tools for sale, or a host of other things to which VBA and Lisp cannot access without great difficulty or at all then this is the API you should use.

--------------------------------------------------------------------------------
The VBA API:
If this is your first time extending the functionality of AutoCAD than this is most likely the API for you. This API is very friendly towards new developers. The Visual Basic language reads in such a way that many times new developers can work out simple questions by just reading the names of the functions. This API does not have as much access to AutoCAD as the C++ or Lisp API's do however you can construct and execute Lisp commands to give yourself access to the few things that Lisp can do which VBA cannot natively. If you are very good with VBA you can subclass the AutoCAD command line and then there really isn't anything Lisp has access to which you wouldn't using VBA. The major drawback to the VBA API is that it doesn't natively register your functionality with AutoCAD. It must first be loaded as a dvb in any of the various ways you can load applications into AutoCAD and then executed via the tools menu or by a custom button or menu item. Depending on your user base this can be a big issue. I have worked on contracts where the drafters are all used to commands and don't want to use anything else. In this case VBA can be a difficult sell. If the user group isn't that stuck in there ways then VBA is usually a very easy sell. Especially after they see how fast you can create tools with it. As with Lisp this is primarily an internal developer's tool to extend AutoCAD within your company, or if you have been contracted to work on site to write custom tools. Out of all the API's this is the one, which can create applications the most quickly especially applications, which require graphic dialogs. It also has the most support from AutoDesk.

--------------------------------------------------------------------------------
The Lisp API:
When I am speaking of Lisp I am specifically referring to AutoLisp and VisualLisp I am not talking about ANSI Common Lisp. First a quick description of AutoLisp. "AutoLisp: it combines the RAD features of iX86 with the flexibility of COBOL". All kidding aside the major reason the Lisp API gets used is because for many developers it satisfies the question "What language am I most comfortable in?". For many people this is where they started and it is what they are fastest developing in. Another reason to use this API is, if the environment in which you work has large legacy libraries of Lisp routines. Lisp is harder than VBA to learn yet still far easier than C or C++. Until AutoCAD 2000, VBA was not very well implemented inside of AutoCAD and left a great deal to be desired. Lisp was the primary choice for rapid in house development of macro's. Large libraries of Lisp functions exist in many places. Re-writing these in VBA is often not cost effective in the short term. If this is the case then Lisp is the tool for you and may God have mercy upon your soul. Kidding sort of. There are some very serious downsides to using Lisp so if you are new to developing for AutoCAD or need to interface your functionality with any other Windows programs or the Windows operating system you may want to look into VBA instead. On the upside if you are interfacing with a program written for the objectARX API it is a lot easier for the objectARX developer to expose their functionality to Lisp than VBA but a good developer should be able to do either so it really depends on who is writing the C++ side of things as to which they expose their functionality to.

--------------------------------------------------------------------------------

Here is a simple checklist for determining which API may be right for your project:
ObjectARX:
You are most comfortable working in C or C++
You need the absolute maximum amount of control over AutoCAD and Windows
You need to write custom objects
You need access to things which are not exposed to VBA or Lisp
You require more speed than can be had using VBA or Lisp
Your workplace requires applications be developed in C or C++
You need to use libraries external to AutoCAD which are only available to C or C++
VBA:
You are most comfortable working in VBA
You need to use a dialogs
You need to interface with Windows or one of the Microsoft office programs like Excel
You are new to developing for AutoCAD or are new to developing period
You require maximum speed of development time yet are not overly worried about application speed
You know you are going to need a lot of help from Autodesk getting your application written
Lisp:
The world ended and there are no other tools available
You are most comfortable working in Lisp
You are working with an AutoCAD version prior to 2000
You are working in one of those gray areas in AutoCAD where Lisp can do something that would require a huge amount of VB knowledge to accomplish the same thing.
Your workplace requires it
Your workplace may need to interface existing Lisp libraries with your tool
You enjoy pain
You don't need any dialogs or graphical user interaction other than the command line/screen pics in your application
Parens make you happy (oh look here come the men in white coats for you now)
--------------------------------------------------------------------------------
Now I will provide what you all come here for really. Free code. Yes, that's right we know that's why you really read this stuff isn't it. So since you suffered through the above I suppose I shall have to reward you with free code so that you come back. In each of the three API's I show a way to edit the first editable attribute in a block reference. The use of "command" will not be seen here as that is a huge pet peeve of mine. If you are using "command" you are not programming you are scripting and they are two completely separate things.
ObjectARX:
void chngAtt()
{
ads_name entres;
ads_point ptres;
AcDbObjectId _Id, _attId;
AcDbObjectIterator *pIttr = NULL;
if(acedEntSel("Select a Block Reference", entres, ptres) != RTNORM )
{
//Selection failed
return;
}
acdbGetObjectId(_Id, entres);
AcDbObjectPointer pRef(_Id,AcDb::kForRead);
if(pRef.openStatus()!=Acad::eOk)
{
//Open failed
return;
}
pIttr = pRef->attributeIterator();
while(!pIttr->done())
{
_attId = pIttr->objectId();
AcDbObjectPointer pAtt(_attId,AcDb::kForWrite);
if(pAtt.openStatus()==Acad::eOk)
{
pAtt->setTextString("We changed this");
break;
}
pIttr->step();
}
delete pIttr;
}
VBA:
Option Explicit
Sub chngAtt()
Dim objEnt As AcadObject
Dim objRef As AcadBlockReference
Dim varAtts As Variant
Dim objAtt As AcadAttributeReference
Dim emptyPt As Variant
ThisDrawing.Utility.GetEntity objEnt, emptyPt, "Select Block: "
If objEnt.ObjectName = "AcDbBlockReference" Then
Set objRef = objEnt
If objRef.HasAttributes Then
varAtts = objRef.GetAttributes
Set objAtt = varAtts(0)
objAtt.TextString = "We changed this"
End If
End If
End Sub
Lisp:
(defun C:chngAtt ()
(setq Mainent (entsel))
(setq entList (entget (car Mainent)))
(setq entAtt (entget (entnext (cdr (assoc -1 entList)))))
(setq entNewAttVal
(subst (cons 1 "We changed this") (assoc 1 entAtt) entAtt)
)
(entmod entNewAttVal)
(entupd (car Mainent))
(princ)
)

评分

参与人数 1金钱 +10 贡献 +1 激情 +1 收起 理由
easypower + 10 + 1 + 1 【精华】好文章好文章

查看全部评分

 楼主| 发表于 2004-12-25 23:41:00 | 显示全部楼层
如何选择AutoCAD的开发工具?

AutoCAD提供了三种主要的开发工具,分别是:使用C/C++的ObjectARX,VB/VBA的ActiveX开发,以及AutoLISP/VisualLISP开发工具。每一个开发者都有自己的爱好,但是抛开所有的偏爱,人们经常想知道哪一种最好,我到底应该选择哪种工具?给这些人的答案是:“它取决于你要完成什么工作。”每一种开发工具都有不同的东西,在某谢情况下都有不可比拟的优点。当决定究竟使用什么开发工具时,你可以问自己四个问题:哪种语言让我感觉最顺手(舒服)?我有多少时间?谁是我的目标用户,他们有多少使用AutoCAD的经验?我到底需要对AutoCAD控制到什么程度,需要多少可能的窗口类型来尽快完成工作?当我介绍不同开发工具所具有的不同功能时,你可能会明白为什么这四个问题是重要的。在谈及这几种开发工具时,我仅仅将它们看作在AutoCAD中使用的功能,而不将它们看作独立的应用程序。
ObjectARX:
在三种开发工具中,这种工具拥有对AutoCAD最深入的控制能力,能够提供最多类型的窗体。使用ARX可以向AutoCAD注册自己的命令,用户运行你的程序时无需了解关于AutoCAD更多的知识。这种便利的代价就是编制ARX程序比VBA和LISP程序需要花费更多的时间,因此用来编制简单的绘图工具有点浪费了。要掌握ARX的前提是你对C和C++非常熟悉,从个人观点来说,我最喜欢这种工具,但那是因为我做的99%的程序都是用C和C++语言,选择ARX意味着我不用学习一门新语言。对我来说,回答“哪种语言让我感觉最顺手?”就足够了。ARX能够访问很多的AutoCAD底层工具(这些东西可能VBA和LISP并不能访问),这是大多数开发者选择ARX的主要原因,他们需要作一些用其他两种开发工具不能完成的工作。此外,这也是唯一一种能够确保你的代码安全(不被别人阅读或非法复制)的开发工具。如果你需要开发自定义实体,使用空间过滤,扩展一个使用其他开发工具的应用程序的功能,正在开发用于销售的第三方工具,或者用到一大堆用VBA和LISP不能访问的东西(或者费很大力气去实现的东西),那么ObjectARX是你的最佳选择。
VBA:
如果你是第一次开发AutoCAD应用程序,那么这就是最适合你的工具!这种工具对初学者来说非常友好,Visual Basic的代码阅读起来非常容易,很多初学者仅读了函数的名称就能理解一个问题。无论如何创建或者执行LISP命令来扩充你的访问手段,这种开发工具没有ARX和LISP那么多对AutoCAD访问的方式(译者注:这也有情可原,毕竟VBA和另外两种开发工具比起来年轻得多!)如果你对VBA非常精通,可以通过再对AutoCAD命令行进行仔细研究和分类(这句话可能不太通顺,原文是:you can subclass the AutoCAD command line),这样你就能实现LISP所能完成的所有功能!对VBA来说,最大的遗憾就是不能向AutoCAD注册命令,必须先用各种加在应用程序的方法将其对应的dvb文件加载,然后通过“工具/宏/宏”菜单项执行,或者在菜单项和自定义的工具栏按钮中执行,如果你的用户的基础知识实在有限,这对你来说是个不小的问题(译者注:已有合适的解决方案)。我曾经研究过很多合同,许多制图者喜欢直接在命令行执行命令,这对VBA(开发工具)的销售不是个好消息(译者注:已经有合适的方法实现这种功能),如果用户组不会在这个问题上纠缠,那么VBA通常是很好的商品,特别是当他们看到你能使用它多么迅速地创建应用程序。和LISP结合起来,VBA首先是一个开发公司内部使用的程序的利器,或者在你已经包工并且需要在现场编写自定义的工具时使用它。在所有的开发工具中,这是一种开发速度最快的工具,特别是在开发需要图形界面(对话框)的程序时。使用这种工具,你同样能从AutoDesk获得最好的技术支持!
LISP:

当我谈到LISP的时候,一般是专指AutoLISP和VisualLISP,而不是在讨论ANSI的通用LISP语言。首先简单描述一下AutoLISP,AutoLISP兼备快速开发工具的特点和COBOL语言的灵活性,很多开发者选择LISP的主要原因是它符合他们对“什么语言让我感到很顺手?”问题的答案,对很多人来说,这是他们第一次开发AutoCAD所使用的语言,并且很快使用该语言进行开发。另一个使用这种开发工具的原因是,你所工作的环境可能已经具有很多LISP程序(的确,AutoLISP的使用历史最为悠久)。学习LISP比VBA难,却又比C和C++简单。直到AutoCAD 2000,VBA还不能很好的在AutoCAD内部执行,并且留下很多开发者希望解决的问题。LISP是快速编写应用程序的最初的开发工具,大量的LISP程序库存在于世界各地在短时间内用VBA重写这些东西不值得,也不容易。如果是这种情况,那么LISP就是为你而打造的开发工具,也许是上帝可怜你,呵呵,开个玩笑。这些年来使用LISP的人大大减少了,如果你是AutoCAD二次开发的初学者,并且你的程序可能要和其他的Windows程序交换数据,你最好去看看VBA。总体来说,如果你正在创建和一个用ARX编写的程序交换数据的程序,对ARX程序员来说,为LISP程序员预留接口比为VBA预留接口要简单一些,但是一个好的程序员应该两者都能做,因此究竟为哪种语言预留接口实际上取决于写C++方面的东西的人。
-------------------------------------
下面就是一个简单的清单,用于决定到底哪种开发工具对你的项目最合适:
ObjectARX:
你必须感到用C和C++最为顺手(译者注:顺手是对一种语言无缘故的喜欢);
你需要大量的对AutoCAD的控制和多种类型的窗体;
你需要自定义对象;
你需要访问一些用VBA和LISP无法访问的东西;
你的程序需要更高的效率(VBA和LISP无法达到);
你的工作环境需要使用C或者C++开发的程序;
你需要使用一些AutoCAD外部的库函数,这些库函数仅能在C和C++中调用。

VBA:
你感觉用VBA编程最顺手;
你需要使用对话框;
你需要和Windows或者一种Office应用程序(例如Excel)交换数据;
你初学AutoCAD二次开发,或者初学编程;
你需要尽快完成一个程序的开发,而程序的效率不是那么重要;
你知道在开发过程中你需要从Autodesk获得大量的帮助。
LISP:
世界末日,没有其他的工具可选(译者注:就是你觉得VBA和ARX都不适合你);
你感觉用LISP编程很顺手;
你要开发的程序在AutoCAD 2000以前的版本上运行;
你的工作涉及到一些特殊的东西,这些东西用LISP可以直接实现,但是如果用VBA来实现要花费很大的力气;
你的工作环境需要它;
你的工作环境需要使用已经存在的LISP函数库;
你喜欢享受痛苦(译者注:可能有作者的一些个人感情色彩);
在你的程序中除了命令行和图形对象之外不需要任何对话框或者图形用户界面;
Parens让你快乐(译者注:不理解这句话的意思,估计Parens是个熟悉LISP开发的人的名字),哦,看这边,那个穿白大衣的人来找你了。
-------------------------------------
现在我将提供一些你们来这里的所有人都想要的东西:免费的代码(译者注:作者仍然是在开玩笑)!当然,我们直到这也是你读这一篇文章的原因,不是吗?因此,既然你费尽千辛万苦读完了上面的文字,我想我应该给你一些免费的代码,这样说不定下次你还会来这里。在每种开发工具的示例代码中,我都给出了一种编辑一个块参照中第一个可编辑的属性的方法,在代码中不会看到使用命令行的语句,因为我不喜欢使用那些东西。如果你使用“Command”(译者注:LISP中的command函数,VBA中的SendCommand方法,ARX中的acedCommand函数),你不是在编程,顶多算是在写脚本(译者注:脚本在这里泛指那些解释执行的语言,从某种意义上讲,使用“Command”确实是要求命令行解释并且执行你所提供的语句),这是两码事。
ObjectARX的代码:------------------------
void chngAtt()
{
ads_name entres;
ads_point ptres;
AcDbObjectId _Id, _attId;
AcDbObjectIterator *pIttr = NULL;
if(acedEntSel("Select a Block Reference", entres, ptres) != RTNORM )
{
//Selection failed
return;
}
acdbGetObjectId(_Id, entres);
AcDbObjectPointer pRef(_Id,AcDb::kForRead);
if(pRef.openStatus()!=Acad::eOk)
{
//Open failed
return;
}
pIttr = pRef->attributeIterator();

while(!pIttr->done())
{
_attId = pIttr->objectId();
AcDbObjectPointer pAtt(_attId,AcDb::kForWrite);
if(pAtt.openStatus()==Acad::eOk)
{
pAtt->setTextString("We changed this");
break;
}
pIttr->step();
}
delete pIttr;
}
VBA:--------------------------------------
Option Explicit
Sub chngAtt()
Dim objEnt As AcadObject
Dim objRef As AcadBlockReference
Dim varAtts As Variant
Dim objAtt As AcadAttributeReference
Dim emptyPt As Variant

ThisDrawing.Utility.GetEntity objEnt, emptyPt, "Select Block: "
If objEnt.ObjectName = "AcDbBlockReference" Then
Set objRef = objEnt
If objRef.HasAttributes Then
varAtts = objRef.GetAttributes
Set objAtt = varAtts(0)
objAtt.TextString = "We changed this"
End If
End If
End Sub
LISP:---------------------------------------
(defun C:chngAtt ()
(setq Mainent (entsel))
(setq entList (entget (car Mainent)))
(setq entAtt (entget (entnext (cdr (assoc -1 entList)))))
(setq entNewAttVal
(subst (cons 1 "We changed this") (assoc 1 entAtt) entAtt)
)
(entmod entNewAttVal)
(entupd (car Mainent))
(princ)
)

<全文完>
发表于 2004-12-27 15:34:00 | 显示全部楼层
我最不喜欢就是lisp里面那么多的括号
发表于 2004-12-28 02:44:00 | 显示全部楼层
真是经典,好好阅读!
发表于 2004-12-29 08:53:00 | 显示全部楼层
好东东.顶一下.
发表于 2005-1-4 08:53:00 | 显示全部楼层
good
发表于 2005-1-4 21:01:00 | 显示全部楼层
分析的不错,很是谢谢!!
发表于 2005-1-6 18:05:00 | 显示全部楼层
好!顶!!!
发表于 2005-1-17 08:42:00 | 显示全部楼层
非常不错 谢谢
发表于 2005-1-18 09:25:00 | 显示全部楼层
谢谢,顶。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-26 10:39 , Processed in 0.177815 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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