zoukankan      html  css  js  c++  java
  • AutoCAD开发选择----ObjectARX还是.net API(转载)

    本文基于AutoCAD 2006新推出的.NET API为工具,介绍了在.NET平台下对AutoCAD进行二次开发的技术,并与目前常用的VBA、ObjectARX作了对比。同时讨论了如何弥补.NET API某些不足的功能。
        
           当前AutoCAD的二次开发工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp与VBA较为简单,特别是 VBA,使用方便且开发速度较快,但其功能相比ObjectARX有所不足,尤其是对面向对象的功能支持不好。而ObjectARX基于VC平台,在C++的支持下,其功能非常强大,可以很好地运用各种面向对象技术,但其缺点是发开速度比较慢,同时对开发人员的能力要求较高。
            .NET是微软新推出的开发平台,具有众多优点。基于.NET平台对AutoCAD进行二次开发,可充分利用.NET的各种优势,在保证功能强大的前提下大大提高开发速度。

    一、基于.NET的开发
        (1).NET API简介
        在新推出的AutoCAD 2006中,Autodesk为其开发增加了.NET API。.NET API提供了一系列托管的外包类(Managed Wrapper Class),使开发人员可在.NET框架下,使用任何支持.NET的语言,如VB.NET、C# 和Managed C++等对AutoCAD进行二次开发。其优点是完全面向对象,在拥有与C++相匹配的强大功能的同时,具有方便易用的特点,是较理想的AutoCAD二次开发工具。
        (2).NET API与传统ObjectARX的主要区别
            .NET API与传统ObjectARX的区别主要源于在.NET环境下开发应用程序与在VC环境下开发应用程序的区别。首先,在VC环境下,程序员需要自己管理 内存的申请和释放,而.NET采用了垃圾回收机制,由.NET框架自行判断内存回收的时机并实行回收,从而解决了令C++程序员头痛的内存泄漏问题。也正 是由于这个特点,在.NET环境下不能象在C++环境下那样利用析构函数释放其他的资源,需要程序员在程序中显式地释放。在.NET API中,主要通过Dispose来函数进行资源的释放。
        其次,ObjectARX中的各种反应器(Reactor)在.NET API中由外包类映射为各种事件(Event),可通过定义这些事件的响应函数来响应AutoCAD的各种操作。同时对于错误信息的处理也从函数返回值改 变为通常异常来处理,使其更好地兼容.NET。由于VB.NET、C#等语言都是完全面向对象的,没有全局函数的概念,所以.NET API将ObjectARX下的全局函数封装为.NET API下的某些对象或对象的属性,如ObjectARX下与用户交互的系列全局函数被封装为CommandLinePrompt类。
        (3)使用.NET API
        下面以C#为例,在Microsoft Visual C# 2005 Express Edition Beta平台上,先新建一个Class Library项目,再将AutoCAD2005安装目录下的acdbmgb.dll与acmgb.dll作为引用添加进项目中。这两个文件包含了. NET API中所有的外包类。
        然后在要使用.NET API的类中添加以下语句以引用.NET API的命名空间。需要添加的语句如下:
            using Autodesk.AutoCAD.ApplicationServices;
            using Autodesk.AutoCAD.DatabaseServices;
            using Autodesk.AutoCAD.Runtime;
            using Autodesk.AutoCAD.Geometry;
        这样就可以利用.NET API进行开发了。以下代码可在AutoCAD注册为一个命令“AddLine”,该命令可在当前工作空间中添加一条起点为(0,0,0),终点(200,200,0)的直线。代码如下:
            [CommandMethod ("AddLine")]
            public static void AddLineCmd()
            {
            Database db = HostApplicationServices.WorkingDatabase;//获得当前工作空间的数据库
            BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead); //获得块表
            BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);    //获得模型空间的块表记录
            Line line = new Line(new Point3d(0, 0, 0), new Point3d(200, 200, 0)); //创建一条直线
            try {
            btr.AppendEntity(line);  //将直线添加到模型空间中
            line.Close();//关闭该直线
            }
            finally {
            btr.Close();//关闭块表记录
            bt.Close();//关闭块表
            }
            }
        由此可见,上述语句与在VC下的开发非常类似,其过程都是先得到数据库,然后依次打开块表、块表记录,接着添加实体,最后关闭块表、块表记录。值得注意的是finally语句,无论try块中的语句是否发生异常,finally块中的语句都会被执行,从而确保关闭块表和块表记录的操作会被执行。
        写完代码后进行编译,编译完成将得到一个dll文件。在AutoCAD 2006中通过“netload”命令即可选择该dll文件进行加载,加载成功后即可以通过“AddLine”命令执行上述代码。遗憾的是目前的.NET API版本还不支持卸载,若要卸载只能关闭AutoCAD。
            (4).NET API的初始化与清除
        在ObjectARX中,“acrxEntryPoint”函数是ARX程序的载入点,程序的初始化和清除均可在该函数中进行。而在.NET API中则首先需要将初始化代码封装在一个类中,同时该类需要压迫实现

            IExtensionApplication接口。该接口包含Initialize与Terminate两个函数。其中Initialize负责加载程序时的初始化操作,Terminate则负责进行卸载程序时的清除操作。代码如下:
    namespace ARXExample {
    public class MyARX : IExtensionApplication {
    ……
    public void Initialize() {
    //初始化操作
    }
    public void Terminate() {
              //清除操作
    }
    ……

    }
    同时,为加快加载速度,可在MyARX.cs的文件头加入以下语句:
    [assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
    [assembly: CommandClass (typeof (ARXExample.MyARX) ) ]
        这样在加载程序时AutoCAD将直接通过MyARX中的Initialize语句进行初始化,同时注册MyARX中的命令。否则,AutoCAD将搜索 dll中所有的类以找到实现IExtensionApplication接口的类进行初始化,如找不到则不进行初始化。同样,通过 CommandClass属性,AutoCAD也会直接到MyARX类中搜索要注册的命令。当程序中包含的类数目较多时,通过 ExtensionApplication和CommandClass这两个属性可显著地加快程序的加载速度。
            (5).NET API与COM交互操作
        在目前的.NET API中,其功能与传统的ObjectARX相比有所不及,有相当的ObjectARX函数目前还没有封装到.NET API中,如GetPoint等。但可以通过COM方式使用ActiveX来弥补.NET API的不足。
    增加了COM引用后,程序就可以使用许多VBA中的功能了。以AutoCAD ActiveX中的事件为例,以下代码可以为当前工作空间中所有的图元添加Modified事件:
    Database db = HostApplicationServices.WorkingDatabase;
    BlockTable bt = (BlockTable)db.BlockTableId.Open(OpenMode.ForRead);
    BlockTableRecord btr = (BlockTableRecord)bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite);
    try {
    AcadObject obj;
    //遍历块表记录
    foreach (ObjectId objId in btr) {
            //由ObjectId得到ActiveX中的AcadObject对象
                obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);
            //为obj添加响应Modified事件
                obj.Modified += new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);
            }
    }
    finally {
            btr.Close();
            bt.Close();
    }
    其中事件响应函数obj_Modified的表示如下所示:
    public static void obj_Modified(AcadObject obj) {
    CommandLinePrompts.Message("object modified!" + obj.ObjectID + " ");
    }
    二、结论
        本文以C#为例,对基于.NET API的AutoCAD二次开发作了较详细的介绍。.NET API在具有ObjectARX强大功能的同时具有VBA使用方便易用的优点,同时具有C++的强大功能,是较为理想的开发工具。但目前.NET API在某些方面还有些不足,但随着其版本的更新、完善,定会成为众多开发人员的首选工具。

    说明:.NET API又是怎么工作的呢?我们都知道ACAD的功能其实是通过ObjectARX来实现的,所以.NET API其实就通过VC++和C++/CLI(原来的VC++.NET)混合编程把ARX功能包装一下以.NET类的形式展示出来。也就是说使用.NET API其实使用的是ARX,而.NET API能实现多少功能就取决于包装的程度,也就是包装了多少ARX的功能。了解ARX的朋友都知道,使用ARX库,由于C++语言的特点,我们经常需要派生ARX类。但使用.NET就不必了,我们经常只需对对应的event来个delegate就行了,相比而言简洁得一塌糊涂(比如:Autodesk.AutoCAD.ApplicationServices.Application.BeginQuit等event)。根据前边对自定义对象的描述,现在就清楚了,.NET API除了部分自定义对象功能外,基本能代替ARX。

  • 相关阅读:
    洛谷P1020/CODEVS1044 导弹拦截(拦截导弹)
    洛谷P1541/CODEVS1068 乌龟棋
    洛谷1791/CODEVS1214线段覆盖
    NOIP2002提高组/洛谷P1031均分纸牌
    【USACO2009Decsilver T1 自私的食草者
    洛谷P1024/NOI题库7891(2.3)/NOIP2001提高组T1 一元三次方程求解
    洛谷1086/NOI题库1.13.38/NOIP2004普及组第2题 花生采摘
    NOIP2010/洛谷P1525关押罪犯
    洛谷P1115最大子段和
    1244-作为一个java开发者的知识储备
  • 原文地址:https://www.cnblogs.com/xiongyunqi/p/5734000.html
Copyright © 2011-2022 走看看