你當(dāng)前的位置>>主頁(yè)>>AutoCAD>>AutoCAD二次開(kāi)發(fā)
 
                        AutoCAD基于NET平臺(tái)的二次開(kāi)發(fā)
 

    摘要:本文基于AutoCAD 2006新推出的.NET API為工具,介紹了在.NET平臺(tái)下對(duì)AutoCAD進(jìn)行二次開(kāi)發(fā)的技術(shù),并與目前常用的VBA、ObjectARX作了對(duì)比。同時(shí)討論了如何彌補(bǔ).NET API某些不足的功能。

    當(dāng)前AutoCAD的二次開(kāi)發(fā)工具主要有:VisualLisp、VBA和ObjectARX等。其中,VisualLisp與VBA較為簡(jiǎn)單,特別是VBA,使用方便且開(kāi)發(fā)速度較快,但其功能相比ObjectARX有所不足,尤其是對(duì)面向?qū)ο蟮墓δ苤С植缓。而ObjectARX基于VC平臺(tái),在C 的支持下,其功能非常強(qiáng)大,可以很好地運(yùn)用各種面向?qū)ο蠹夹g(shù),但其缺點(diǎn)是發(fā)開(kāi)速度比較慢,同時(shí)對(duì)開(kāi)發(fā)人員的能力要求較高。
NET是微軟新推出的開(kāi)發(fā)平臺(tái),具有眾多優(yōu)點(diǎn);.NET平臺(tái)對(duì)AutoCAD進(jìn)行二次開(kāi)發(fā),可充分利用.NET的各種優(yōu)勢(shì),在保證功能強(qiáng)大的前提下大大提高開(kāi)發(fā)速度。

     一、基于.NET的開(kāi)發(fā)

   1..NET API簡(jiǎn)介

    在新推出的AutoCAD 2006中,Autodesk為其開(kāi)發(fā)增加了.NET API。.NET API提供了一系列托管的外包類(Managed Wrapper Class),使開(kāi)發(fā)人員可在.NET框架下,使用任何支持.NET的語(yǔ)言,如VB.NET、C# 和Managed C 等對(duì)AutoCAD進(jìn)行二次開(kāi)發(fā)。其優(yōu)點(diǎn)是完全面向?qū)ο,在擁有與C 相匹配的強(qiáng)大功能的同時(shí),具有方便易用的特點(diǎn),是較理想的AutoCAD二次開(kāi)發(fā)工具。

    2..NET API與傳統(tǒng)ObjectARX的主要區(qū)別

    NET API與傳統(tǒng)ObjectARX的區(qū)別主要源于在.NET環(huán)境下開(kāi)發(fā)應(yīng)用程序與在VC環(huán)境下開(kāi)發(fā)應(yīng)用程序的區(qū)別。首先,在VC環(huán)境下,程序員需要自己管理內(nèi)存的申請(qǐng)和釋放,而.NET采用了垃圾回收機(jī)制,由.NET框架自行判斷內(nèi)存回收的時(shí)機(jī)并實(shí)行回收,從而解決了令C 程序員頭痛的內(nèi)存泄漏問(wèn)題。也正是由于這個(gè)特點(diǎn),在.NET環(huán)境下不能象在C 環(huán)境下那樣利用析構(gòu)函數(shù)釋放其他的資源,需要程序員在程序中顯式地釋放。在.NET API中,主要通過(guò)Dispose來(lái)函數(shù)進(jìn)行資源的釋放。

  其次,ObjectARX中的各種反應(yīng)器(Reactor)在.NET API中由外包類映射為各種事件(Event),可通過(guò)定義這些事件的響應(yīng)函數(shù)來(lái)響應(yīng)AutoCAD的各種操作。同時(shí)對(duì)于錯(cuò)誤信息的處理也從函數(shù)返回值改變?yōu)橥ǔ.惓?lái)處理,使其更好地兼容.NET。由于VB.NET、C#等語(yǔ)言都是完全面向?qū)ο蟮模瑳](méi)有全局函數(shù)的概念,所以.NET API將ObjectARX下的全局函數(shù)封裝為.NET API下的某些對(duì)象或?qū)ο蟮膶傩,如ObjectARX下與用戶交互的系列全局函數(shù)被封裝為CommandLinePrompt類。

    3.使用.NET API

   下面以C#為例,在Microsoft Visual C# 2005 Express Edition Beta平臺(tái)上,先新建一個(gè)Class Library項(xiàng)目,再將AutoCAD2005安裝目錄下的acdbmgb.dll與acmgb.dll作為引用添加進(jìn)項(xiàng)目中.這兩個(gè)文件包含了NET API中所有的外包類。

  然后在要使用.NET API的類中添加以下語(yǔ)句以引用.NET API的命名空間。需要添加的語(yǔ)句如下:

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Geometry;

   這樣就可以利用.NET API進(jìn)行開(kāi)發(fā)了。以下代碼可在AutoCAD注冊(cè)為一個(gè)命令“AddLine”,該命令可在當(dāng)前工作空間中添加一條起點(diǎn)為(0,0,0),終點(diǎn)(200,200,0)的直線。代碼如下:

[CommandMethod ("AddLine")]
public static void AddLineCmd()
{
Database db = HostApplicationServices.WorkingDatabase;//獲得當(dāng)前工作空間的數(shù)據(jù)庫(kù)
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));//創(chuàng)建一條直線
try {
btr.AppendEntity(line);//將直線添加到模型空間中
line.Close();//關(guān)閉該直線
}
finally {
btr.Close();//關(guān)閉塊表記錄
bt.Close();//關(guān)閉塊表
}
}

   由此可見(jiàn),上述語(yǔ)句與在VC下的開(kāi)發(fā)非常類似,其過(guò)程都是先得到數(shù)據(jù)庫(kù),然后依次打開(kāi)塊表、塊表記錄,接著添加實(shí)體,最后關(guān)閉塊表、塊表記錄。值得注意的是finally語(yǔ)句,無(wú)論try塊中的語(yǔ)句是否發(fā)生異常,finally塊中的語(yǔ)句都會(huì)被執(zhí)行,從而確保關(guān)閉塊表和塊表記錄的操作會(huì)被執(zhí)行。

  寫(xiě)完代碼后進(jìn)行編譯,編譯完成將得到一個(gè)dll文件。在AutoCAD 2006中通過(guò)“netload”命令即可選擇該dll文件進(jìn)行加載,加載成功后即可以通過(guò)“AddLine”命令執(zhí)行上述代碼。遺憾的是目前的.NET API版本還不支持卸載,若要卸載只能關(guān)閉AutoCAD。

    4..NET API的初始化與清除

  在ObjectARX中,“acrxEntryPoint”函數(shù)是ARX程序的載入點(diǎn),程序的初始化和清除均可在該函數(shù)中進(jìn)行。而在.NET API中則首先需要將初始化代碼封裝在一個(gè)類中,同時(shí)該類需要壓迫實(shí)現(xiàn)
IExtensionApplication接口。該接口包含Initialize與Terminate兩個(gè)函數(shù)。其中Initialize負(fù)責(zé)加載程序時(shí)的初始化操作,Terminate則負(fù)責(zé)進(jìn)行卸載程序時(shí)的清除操作。代碼如下:

namespace ARXExample {
public class MyARX : IExtensionApplication {
……
public void Initialize() {
//初始化操作
}
public void Terminate() {
//清除操作
}
……

}
同時(shí),為加快加載速度,可在MyARX.cs的文件頭加入以下語(yǔ)句:
[assembly: ExtensionApplication (typeof (ARXExample.MyARX) ) ]
[assembly: CommandClass (typeof (ARXExample.MyARX) ) ]

這樣在加載程序時(shí)AutoCAD將直接通過(guò)MyARX中的Initialize語(yǔ)句進(jìn)行初始化,同時(shí)注冊(cè)MyARX中的命令。否則,AutoCAD將搜索dll中所有的類以找到實(shí)現(xiàn)IExtensionApplication接口的類進(jìn)行初始化,如找不到則不進(jìn)行初始化。同樣,通過(guò)CommandClass屬性,AutoCAD也會(huì)直接到MyARX類中搜索要注冊(cè)的命令。當(dāng)程序中包含的類數(shù)目較多時(shí),通過(guò)ExtensionApplication和CommandClass這兩個(gè)屬性可顯著地加快程序的加載速度。

     5..NET API與COM交互操作

   在目前的.NET API中,其功能與傳統(tǒng)的ObjectARX相比有所不及,有相當(dāng)?shù)腛bjectARX函數(shù)目前還沒(méi)有封裝到.NET API中,如GetPoint等。但可以通過(guò)COM方式使用ActiveX來(lái)彌補(bǔ).NET API的不足。
增加了COM引用后,程序就可以使用許多VBA中的功能了。以AutoCAD ActiveX中的事件為例,以下代碼可以為當(dāng)前工作空間中所有的圖元添加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對(duì)象
obj = (AcadObject)((AcadDatabase)db.AcadDatabase).ObjectIdToObject(objId.OldId);
//為obj添加響應(yīng)Modified事件
obj.Modified = new IAcadObjectEvents_ModifiedEventHandler(obj_Modified);
}
}
finally {
btr.Close();
bt.Close();
}
其中事件響應(yīng)函數(shù)obj_Modified的表示如下所示:
public static void obj_Modified(AcadObject obj) {
CommandLinePrompts.Message("object modified!" obj.ObjectID "\n");
}

      二、結(jié)論

   本文以C#為例,對(duì)基于.NET API的AutoCAD二次開(kāi)發(fā)作了較詳細(xì)的介紹。.NET API在具有ObjectARX強(qiáng)大功能的同時(shí)具有VBA使用方便易用的優(yōu)點(diǎn),同時(shí)具有C 的強(qiáng)大功能,是較為理想的開(kāi)發(fā)工具。但目前.NET API在某些方面還有些不足,但隨著其版本的更新、完善,定會(huì)成為眾多開(kāi)發(fā)人員的首選工具。

民眾工作室.制作      版權(quán)所有