By Adam Nagy
Sometimes a function is not available in a higher level API (COM or .NET) but only in the underlying C++ API. Not all is lost in such a case.
In the following example we'll see how we can access the AecAppDbx::drawingPromoterAndIniter function of the OMF 2010 C++ API from a .NET AddIn.
Note: there is an easier way to get the drawing opened in the background fully loaded: http://adndevblog.typepad.com/aec/2012/09/problems-reading-an-aec-side-database-with-a-mode-other-than-sh_denyno.html, but that's not what this current article is about.
You have two options to access C++ functions from your .NET AddIn:
1) Create a .NET wrapper for this function
You can simply create a new ARX project with OMF and .NET support using the ObjectARX Wizard in Visual Studio and then add the following somewhere in the project, e.g. in acrxEntryPoint.cpp:
public ref class Aen1AecUtils { public: static void drawingPromoterAndIniter( Autodesk::AutoCAD::DatabaseServices::Database^ db, System::Boolean sideDb) { AcDbDatabase* pDb = static_cast(db->UnmanagedObject.ToPointer()); AecAppDbx::drawingPromoterAndIniter(pDb, sideDb); } };
Now you can reference the assembly/dll from your .NET application:
[CommandMethod("OpenSideDatabase")] public static void OpenSideDatabase() { using (Database db = new Database(false, true)) { db.ReadDwgFile( @"C:\temp\test.dwg", System.IO.FileShare.None, false, ""); Aen1AecUtils.drawingPromoterAndIniter(db, true); // read/write the database } }
2) Use P/Invoke to call the OMF function from your .NET code
Based on the structure of the OMF SDK you can find out which library you need to check for the entry point of AecAppDbx::drawingPromoterAndIniter()
The function is declared in AecAppDbx.h, which is in the AecBase folder, so the function is inside the AecBase.lib (AecBase.dbx), whose 32 bit version resides in the lib-win32 folder.
If you use depends.exe (Dependency Walker, part of Visual Studio) to see the exported function in AecBase.dbx, then you will not find this function listed. That is because it is exported with the NONAME option.
So instead you need to use dumpbin.exe (part of Visual Studio). The easiest thing is just to open up "Microsoft Visual Studio 2008 > Visual Studio Tools > Visual Studio 2008 Command Prompt" and use it from there to list the exported functions in a text file, where you can search for the function you need, e.g.:
dumpbin "c:\OMF2010.56.0.final\lib-win32\AecBase.lib"
/EXPORTS /OUT:"c:\AecBase.txt"
Since the function name is not exported, use the function's ordinal number [875] instead to P/Invoke it:
[DllImport("AecBase.dbx", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode, EntryPoint = "#875")] public extern static void drawingPromoterAndIniter(
IntPtr db, bool sideDb); [CommandMethod("OpenSideDatabase")] public static void OpenSideDatabase() { using (Database db = new Database(false, true)) { db.ReadDwgFile( @"C:\temp\test.dwg", System.IO.FileShare.None, false, ""); drawingPromoterAndIniter(db.UnmanagedObject, true); // read/write the database } }