本文基於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的各類優點,在保證功能強大的前提下大大提升開發速度。程序員
1、基於.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 + "\n");
}
2、結論
本文以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。app