- UID
- 50069
- 积分
- 0
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2003-5-17
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
摘要:
本文详细讨论了利用一种新的面向对象的开发工具ARX对通用计算机辅助设计软件包AutoCAD进行二次开发的方法并通过将其与Autolisp、ADS软件开发环境相比较得出其优越性所在。
关键词:
ARX,面向对象,IPC
引言
AutoCAD是应用广泛的通用计算机辅助设计软件包。其强大生命力在于它的通用性,多种工业标准和开放体系结构。在软件接口方面AutoCAD提供了三种软件开发环境:Autolisp、ADS和ARX。Autolisp是一种解释型语言,运行速度较慢,同时其能力有限;ADS是开发AutoCAD的C语言设计环境;ARX是自AutoCAD R13版开始特有的面向对象C++开发环境、功能强大、运算效率高。通过在CAD应用系统的应用表明,它的许多新特性能实现许多原来开发环境难以实现的功能,提高开发效率。ARX代表着AutoCAD的发展方向,将成为新一代应用软件开发的首选工具。本文将对ARX面向对象编程环境、方法及其优越性作一详细论述。
ARX面向对象编程环境
ARX编程环境
ARX编程环境提供了面向对象的C++应用程序编程接口,使开发者能够更加深入的使用、用户化和扩展AutoCAD。ARX库包含了一系列工具,开发者利用AutoCAD的开放体系结构可方便的直接访问AutoCAD的数据库结构、图形系统以及进行内部命令定义。
ARX环境主要有AcRx、AcEd、Acdb、AcRx、AcGi、AcGe和ADS类库组成。AcRx库提供了系统级类,用于捆绑应用程序和运行时刻类的注册与鉴别。AcRx库同时提供了大量的宏定义,用于创建新的ARX类。AcEd库提供了命令定义和注册类。AcEd库还提供了系统事件通报类。AcDb库是AutoCAD数据库接口例程库,可对图形对象和非图形对象进行查询和操作。AcGi和AutoCAD实体渲染图形接口库用来完成图形实体的绘制工作。AcGe为公共几何对象实用工具库。ADS库为C语言库,典型的ARX用ADS库进行诸如实体选择、操作选择集、数据获取等操作。
从AutoCAD的发展趋势看,
在利用VC++编制具有Windows风格的用户接口方面,ARX将会提供更多的类和函数,从而代替ADS。
ARX与ADS、Autolisp的比较
ARX与ADS、Autolisp均是AutoCAD提供的内嵌式语言。其中Autolisp是一种解释型语言,它通过内部进程通讯(IPC)与AutoCAD进行通讯;ADS是用C语言编写的应用程序,它以外部函数形式加载到AutoCAD中,需通过Autolisp解释器调用,也是通过IPC与Autolisp通讯,固它们与AutoCAD是相互分离的过程。(如图一所示)ARX与ADS不同,它以动态链接库(DLL)的形式与AutoCAD共享同一地址空间,直接调用AutoCAD的核心函数,并可直接访问AutoCAD数据库。与前两者相比,ARX速度更快,运行更稳定、简单。
ARX面向对象编程及其优越性
ARX应用程序初始化
ARX应用程序的初始化通过InitApp()来完成,如下所示:
void initApp()
{
acedRegCmds->addCommand("ASDK_TEST",
"ASDK_TT", "TEST", ACRX_CMD_MODAL, test);
}
ARX均采用AcEd类实现命令注册,采用此法向AutoCAD添加的新命令与AutoCAD内置命令有着相同的特性和地位,我们称之为本地命令。一种典型地命令注册方式如下:
AcEd::Errorstatus
AcEdCommandStack::addCommand
( const char * cmdGroupName, const char * cmdGlobalName,
const char * cmdLocalName, Adesk::Int32 commandFlags,
AcRxFunctionPtr functionAddr)
其中
cmdGroupName指命令将要添加至组的ASCII码表示,如组不存在则在命令加入之前 将建立该组。
cmdGlobalName 指将要添加命令的ASCII码表示(全局名)
cmdLocalName 指将要添加命令的ASCII码表示(当地名)
commandFlags 与命令相关的标识,可能值有ACRX_CMD _TRANSPARENT,
ACRX_CMD_MODAL,ACRX_CMD_USEPICKSET和
ACRX_CMD_REDRAW,
FunctionAddr 当命令被AutoCAD调用时所执行函数的地址
ARX入口函数
ARX和ADS应用以不同的方式与AutoCAD进行交互。一个ADS的应用包含了一单一无限循环等待Autolisp请求的过程,而一ARX应用则有一主入口点进行消息循环。在你注册命令时他们又将成为额外加到应用中的入口。在你重载ARX库的C++类的虚函数时,这些函数也将成为进入应用的入口点。通用入口函数如下:
AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg) {
case AcRx::kInitAppMsg:
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
}
return AcRx::kRetOK;
}
卸载函数
卸载函数一般采用如下方式:
void unloadApp()
{
acedRegCmds->removeGroup("ASDK_TEST");
}
优越性
一般来说ARX API要比ADS API简单得多,例如现在要改变一直线所在的层ARX、ADS的代码分别如下:
void changeLayer(const AcDbObjectId& entId,
const char* pNewLayerName)
{
AcDbEntity *pEntity;
acdbOpenObject(pEntity, entId, AcDb::kForWrite);
pEntity->setLayer(pNewLayerName);
pEntity->close();
}
从这里可以看出ARX是一完全面向对象的,利用其提供的各类对象即可完成各种复杂操作。(注:此处略去了错误检查)相反在ADS中实体信息是以一结果缓冲器链表表示的,要改变直线所在的层必须完成四步操作:
用ads_entget()获取实体信息
找到包含层值的字段
改变表中的字段
调用ads_entmod()通过修改后的结果缓冲器链表引起数据库的改变
void
changeLayerADS(ads_name entityName,
const char* pNewLayerName)
{
struct resbuf *pRb, *pTempRb;
pRb = ads_entget(entityName);
//不必检查 pRb = NULL ,因为任意实体都属于某一层
for (pTempRb = pRb; pTempRb->restype != 8;
pTempRb = pTempRb->rbnext)
{ ; }
free(pTempRb->resval.rstring);
pTempRb->resval.rstring
= (char*) malloc(strlen(pNewLayerName)
+ 1);
strcpy(pTempRb->resval.rstring, pNewLayerName);
ads_entmod(pRb);
ads_relrb(pRb);
ads_retvoid();
}
从以上代码可看出ARX是直接对数据库进行操作,而ADS、Autolisp则是通过对实体操作来间接操作数据库(Autolisp与ADS类似,所以上面没有举例),显而易见直接对系统最底层进行操作无论从速度上还是功能上都有了极大提高。
结论
作者利用ARX进行拉延模CAD系统的开发,大大提高了编程效率且可利用MFC(Microsoft Fundation Class)得到具有Windows风格的界面。ARX是AutoCAD二次开发的必然趋势,我们应当充分利用ARX提供的类和函数深入到AutoCAD系统内部,实现系统功能要求,提高开发效率。 |
|