350 likes | 560 Views
.Net. Martin Ota otam@fel.cvut.cz. Co je vlastn ě .Net?. Vlastnosti .Net. Využívá se .Net Framework Musí být přítomen Záleží na verzi, t.č. se používají verze 1.0, 1.1 a 2.0 Jiná strategie kompilace a běhu Kompilace do mezijazyka MSIL – u „dodavatele“ (Microsoft Intermediate Langugae)
E N D
.Net Martin Ota otam@fel.cvut.cz
Vlastnosti .Net • Využívá se .Net Framework • Musí být přítomen • Záleží na verzi, t.č. se používají verze 1.0, 1.1 a 2.0 • Jiná strategie kompilace a běhu • Kompilace do mezijazyka MSIL – u „dodavatele“(Microsoft Intermediate Langugae) • Kompilace JIT (Just In Time) u „konzumenta“ • CLR – Commnon Language Runtime • Shodné pro všechny jazyky (mj. sjednocuje množinu datových typů) • Jiná správa paměti – Gargabe Collection • Jazyková „nezávislost“ • C# jako hlavní jazyk • Specifické C++ „pro zpátečníky“ (managed a klasické unmanaged)
Role .Net v AutoCADu • .Net je aktuální systémovou platformou Windows • AutoCAD verze 2004 evidentně využívá .Net • Povinná přítomnost .Net Frameworku • Palety nástrojů ve WinForms • Konfigurační souborycelé_jméno_soubou.i_s_příponou.config • Verze 2005, 2006 a 2007 poskytují API pro .Net • .Net ObjectARX Managed Wrappers
Obecné rysy • Jazyková nezávislost • Primitivní typy C++ mapovány naodpovídající typy v .Net Framework • bool System.Boolean • Adesk::Boolean System.Boolean • Obal pro ObjectDBX • acdbmgd.dll – součástí SDK • Obal pro ObjectARX • acmgd.dll – součástí AutoCADu
Správa paměti • V .Net je garbage collection, ale... • U objektových obalů je místo destruktorů implementováno rozhraní IDisposable • Děděno z DisposableWrapper • Je to obal unmanaged classesnespoléhat na garbage collection, volat Dispose pro uvolňování systémových zdrojů a paměti (resp. využít using(){}) • managed wrapper nemusí být pokaždé tentýž pro shodný ukazatel na unmanaged class • pozor na porovnání (využívat metody Equals a GetHashCode*), nikoliv ==) *) GetHashCode vrací unmanaged pointer
Správa paměti – podpora IDisposable • Kód Transaction trans = db.TransactionManager.StartTransaction(); try { // ... } finally { trans.Dispose();// tímto se supluje destruktor } • je ekvivalentní kódu: using (Transaction trans = db.TransactionManager.StartTransaction()) { // ... }
Chybové stavy • Ústup od návratových kódů ObjectARX • Systém výjimek • Některé výjimky jsou mapovány na standardní výjimky .Net • Většina ostatních se mapuje na nově definované třídy výjimek • Základní třída výjimky:Autodesk.AutoCAD.Runtime.Exception • Vlastnost ErrorStatus obsahuje původní chybový kód – pro .Net je výčet typu: Autodesk.AutoCAD.Runtime.ErrorStatus
Vlastnosti • V C++ neexistuje konstrukt vlastnosti • Nahrazuje se pomocnými konstrukcemi(i v ObjectARX) • Privátní nebo chráněná data • Přístupové metody getXxx a/nebo setXxx • .Net managed wrappers využívají vlastnosti • klasické C++: AcGeMatrix3d::getCoordSystem() • C#:Autodesk.AutoCAD.Geometry. Matrix3d.CoordinateSystem3d
Události • ObjectARX pro C++ – správa událostí systémem reaktorů • Třídy zdroje události s metodami AddReactor a RemoveReactor (resp. obdobné mechanizmy) • Abstraktní třídy reaktorů s virtuálními funkcemi pro dědění uživatelských reaktorů • Standardní mechanizmus pro .Net – události • .Net managed wrappers poskytují můstek mezi reaktory a událostmi
Události – ukázka (naivní) (I) using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.EditorInput; namespace MyDotNet { public class MyApp { private static Editor editor = null; [CommandMethod("ERA", CommandFlags.Session)] public static void Activate() { if (editor != null|| Application.DocumentManager.MdiActiveDocument == null|| Application.DocumentManager.Count == 0|| Application.DocumentManager.MdiActiveDocument.Editor== null) return;
Události – ukázka (naivní) (II) editor=Application.DocumentManager.MdiActiveDocument.Editor; editor.PromptingForPoint +=newPromptPointOptionsEventHandler(editor_PromptingForPoint); } [CommandMethod("ERD", CommandFlags.Session)] public static void Deactivate() { if (editor != null) { editor.PromptingForPoint -= newPromptPointOptionsEventHandler(editor_PromptingForPoint); editor = null; } }
Události – ukázka (naivní) (III) private static voideditor_PromptingForPoint(object sender, EventArgs e) { editor.WriteMessage(" **PromptingForPoint** "); } } } • Čím je ukázka naivní? • Předpokládá jediný dokument (režim SDI) • Plnohodnotné řešení • Monitorování událostí přepínání dokumentů (správa jako zde) • Správa událostí editoru pro každé dokument/editor zvlášť
Kolekce a iterace kolekcemi • V ObjectARX pro C++ nesystematicky • Net managed wrappers sjednocují přístup • Dvě standardní rozhraní • IEnumerable(s metodou GetEnumerator – pro kolekce) • IEnumerator (pro iterátory) • Podpora LISPovských seznamů • Zavedena třída ResultBuffer • Obdoba structresbuf z ADS
Registrace příkazů • V ObjectARX pro C++ registrace probíhá • Buď voláním funkce s parametrem funkce příkazu • Nebo využitím makra a třídy aplikace(objektový obal prvního způsobu) • .Net managed wrappers zavádějí deklarativní přístup – využit mechanizmus atributů [CommandMethod("PRIKAZ", CommandFlags.Session)] public static void prikaz () { // tělo příkazu }
Globální funkce • ObjectARX pro C++ je definuje, v .Net managed wrappers globální funkce neexistují • Mapují se jako nové funkce nebo vlastnosti do existujících nebo nových tříd • např. nová třída CommandLinePrompt manipuluje s příkazovým řádkem AutoCADu – zapouzdřuje odpovídající dříve globální funkce • acdbTransactionManagerPtr() – přidána vlastnost TransactionManager k objektu databáze
Od C++ k .Net • „Slovník“ tříd, jejich metod, vlastností a bývalých globálních funkcích je v dokumentaci • ObjectARX 2006\docs\arxref.chm • AutoCAD Managed Class Reference • Mapping ObjectARX Identifiers to Managed Names • ObjectARX Classes to Managed Classes • ObjectARX Functions to Managed Members
Jmenné prostory • Mapování tříd většinou „1:1“, místo předpony jmenný prostor:
Jak na to? (I) • Mělo by to být shodné pro jakýkoliv jazyk v .Net(s výjimkou konkrétní syntaxe jazyka, samozřejmě) • Vytvoří se knihovna tříd (Class Library – project/solution) • Přidá se odkaz na .Net managed wrappers • Add Reference v menu Project, nebo v Solution Exploreru • Z adresáře AutoCADu(např. C:\Program Files\AutoCAD 2007)se přidají reference na knihovny acdbmgd.dll a acmgd.dll
Jak na to? (II) • Nakonec je vhodné do zdrojového kódu přidat použití patřičných jmenných prostorů – pro C# např.: using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; • Není to nutné, a pozor, ani vždy vhodné (nejednoznačné názvy) • Načítání není přes _appload, ale přes _netload • To je vše • Je to snadné – žádné nastavování projektů jako v C++ • Ke konfliktům verzí knihoven a/nebo jazyků jako u ObjectARX pro C++ nedochází (vazba je výrazně volnější)!
Příklad using System; using System.Windows.Forms; // Nutno přidat referenci na System.Windows.Forms using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; namespace dotnet { public class Gong { [CommandMethod("-GONG", CommandFlags.Session)] public static void CmdGong() { Autodesk.AutoCAD.ApplicationServices .Application.DocumentManager.MdiActiveDocument.Editor .WriteMessage ("Gong oznámí: " + DateTime.Now.ToString ()); } [CommandMethod("GONG", CommandFlags.Session)] public static void WinCmdGong() { MessageBox.Show ("Gong oznámí: " + DateTime.Now.ToString ()); } } }
Porovnání ObjectARX pro C++ a pro .Net AcDbObjectId createLine() { AcDbLine *pLine=new AcDbLine ( AcGePoint3d (4.0, 2.0, 0.0), AcGePoint3d (10.0, 7.0, 0.0)); AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase() ->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt (ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite); pBlockTable->close(); AcDbObjectId lineId; pBlockTableRecord->appendAcDbEntity(lineId, pLine); pBlockTableRecord->close(); pLine->close(); return lineId; }
Porovnání ObjectARX pro C++ a pro .Net (I) using System; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry;// Přidáno pro Point3d using Autodesk.AutoCAD.Runtime; namespace MyDotNet { public class MyApp { [CommandMethod("MYLINE", CommandFlags.Modal)] public static void MyLine() { using (Database db = HostApplicationServices.WorkingDatabase) { using(Transaction trans=db.TransactionManager.StartTransaction()) { try {
Porovnání ObjectARX pro C++ a pro .Net (II) using (BlockTable bt =(BlockTable)trans.GetObject(db.BlockTableId,OpenMode.ForRead)) { using (BlockTableRecord btr =(BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite)) { using (Line line = new Line(new Point3d(4.0, 2.0, 0.0),new Point3d(10.0, 7.0, 0.0))) { btr.AppendEntity(line); trans.AddNewlyCreatedDBObject(line, true); }// using line (zde proběhne line.Dispose()) }// using btr (zde proběhne btr.Dispose()) } // using bt (zde proběhne bt.Dispose()) trans.Commit(); } // try
Porovnání ObjectARX pro C++ a pro .Net (III) catch (System.Exception ex) { trans.Abort(); Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString()); }// catch }// using trans (zde proběhne trans.Dispose()) }// using db (zde proběhne db.Dispose()) }// method MyLine }// class MyApp }// namespace MyDotNet
WinForms a přizpůsobování • WinForms • Standardní podpora windows-based GUI v .Net • Další cesta jak programovat uživatelské rozhraní AutoCADu • Totálně se liší od MFC • Formulářová orientace • Událostní model • Kontexty, pera apod. nahrazeny vlastnostmi • Přizpůsobování • Přibývá specifická podpora správy CUI (bývalé MNU)
.Net v AutoCADu(jak na starší verze, tj. R14-2004)(..., lze použít i na nové, tj. 2005-2007)
Využití rozhraní COM v .Net • AutoCAD nabízí rozhraní COM (od verze R14) • .Net je „kompatibilní“ s COM • Dokumentace, příklady, ... • Objektový model rozhraní viz VBA • Ostatní přejmout z VBA a přizpůsobit syntaxi použitého jazyka v .Net(pro VB.NET netřeba přizpůsobovat téměř nic)
Využití rozhraní COM v .Net – příklad (I) using System; // Nutno reference na acax17ENU.tlb a axdb17enu.tlb (jsou v ObjectARX\inc). // Pro patřičné verze AutoCADu odpovídá číslo verze TLB using AcadInter = Autodesk.AutoCAD.Interop; using AcadCommon = Autodesk.AutoCAD.Interop.Common; namespace AcadCom { class Program { static void Main(string[] args) // Jde o konzolovou aplikaci { try { AcadInter.AcadApplication acad=(AcadInter.AcadApplication)System.Runtime.InteropServices.Marshal.GetActiveObject("AutoCAD.Application.17"); // Číslo verze AutoCADu musí odpovídat patřičné verzi // (lze zjistit v registrech)
Využití rozhraní COM v .Net – příklad (II) try { double[] startPt = { 100, 150, 0 }; double[] endPt = { 350, 200, 0 }; acad.ActiveDocument.ModelSpace.AddLine(startPt, endPt); } catch (Exception ex) { acad.ActiveDocument.Utility.Prompt(ex.Message); } System.Console.WriteLine("ACAD Communication: OK..."); } catch (Exception ex) { System.Console.WriteLine("Error: " + ex.Message); } } } }
Přímá podpora .Net v Inventoru není • Inventor nabízí rozhraní COM – lze využít v .Net • Runtime Callable Wrapper • Umožní v .Net užívat API Inventoru (založené na COM) • COM Callable Wrapper • Umožní využít .Net-komponentu Inventorem • Problémy se silnými jmény
Děkuji za pozornost... Martin Ota otam@fel.cvut.cz