ObjectARX® Best Practices Davis Augustine Autodesk, Inc. © 2011 Autodesk Class Summary We will cover concepts and practices important for ObjectARX developers. Key areas include general application organization, development tools, localization, user interface and logic separation, error handling, portability, performance, extensibility, installation, maintenance, testing, and debugging. © 2011 Autodesk What we’ll Discuss Not a primer – more of a sampling of best practices See developer support and training for comprehensive how-to’s My background is in AutoCAD internals, database and dwg frameworks ObjectARX involves native C++, not .NET See other classes for .NET best practices Upcoming Release features still under NDA Refer to Monday’s ADN conference © 2011 Autodesk Some Related Classes AutoCAD® 2012 Application Autoloader Technology Revealed Moving from Desktop to Cloud Bill Adkison: CP4284 – Thur 8:15am Parallel Programming in an AutoCAD® Application Asheem Mamoowala: CP6280 - Wed 3pm How Do You Do? And Undo? And Redo? And Undo from Redo? Albert Szilvasy: CP5163 – Wed 8:15am Porting ObjectARX® Applications and User Interfaces to AutoCAD® for Mac® Fenton Webb: CP2080 – Tues 1:15pm Gopinath Taget: CP2526 – Thur 1:15pm Improving Your ObjectARX® C++ Code Mike Dickason: CP5177 – Thur 3:15pm © 2011 Autodesk ObjectARX vs Other Technologies .NET “Managed” languages. C# Safer, more powerful and more friendly WPF U/I framework Not available on Mac There is a third party technology called Mono Does not support custom classes (enablers) VBA Not well supported in 64-bit Not available on Mac Will be removed soon © 2011 Autodesk ObjectARX vs Other Technologies Visual LISP Oldest extension technology. Easy to write and deploy U/I options limited – DCL DCL also available to C++, is platform independent Can access COM model Nice GUI Scripts Limited to what you can send on the command line Use CUI to override and customize commands © 2011 Autodesk Tools and SDKs Microsoft Visual Studio 2010 (SP1) Install both 32-bit (x86) and 64-bit (x64) support (not IA64) ObjectARX SDK for Windows Can do all development on 64-bit Windows and cross compile But can’t run 32-bit AutoCAD on 64-bit OS Mac XCode IDE ObjectARX SDK for the Mac 64-bit only © 2011 Autodesk Big Split – Application Stack ARX apps AutoCAD Windows ARX apps AutoCAD for Server/Console CRX apps AcCore.dll DBX apps AcDbXX.dll AutoCAD Mac AutoCAD Core Engine © 2011 Autodesk Project Types - ARX ARX, CRX and DBX Modules All are essentially DLLs Must match 32 or 64 bit-ness of main EXE ARX implements Graphical U/I Dialogs, Tool palettes, Requires AutoCAD or a vertical (e.g. ADT) as the host app Can be done in .NET also Currently often contains the CRX component Often platform (Mac or Windows) specific Should be an MFC extension on Windows © 2011 Autodesk Project Types – CRX CRX implements business logic Can run on CoreDll-based Host Apps Platform independent (Mac, Windows, WS) Should not use MFC May be driven by ARX App Through command strings or C++ function calls © 2011 Autodesk Project Types – DBX DBX (enabler) implements a custom class More complicated to develop Proxy and versioning issues Can load under Real-Dwg based Apps Usually do not define commands or functions Cannot be done in .NET Should not use MFC Consider using Overrules instead © 2011 Autodesk Windows ARX Using MFC ARX can be an MFC extension DLL Must link to dynamic MFC lib, not static lib MFC is a “mature” framework Use AcUi and AdUi classes to implement dialogs, toolbars, etc Work with AutoCAD windows better than standard MFC classes Provide functionality not available in standard MFC Tabbed dialogs, interaction with AutoCAD windows, TextTips, DrawTips, etc, etc © 2011 Autodesk Localization and Resources Keep strings, bitmaps etc in resource dlls Translate the resource dll to different locales Visual Stdio sets up projects this way automatically MFC often uses a default resource module CString::LoadString(UInt nId); AfxSetResourceHandle(), AfxGetResourceHandle() CAcModuleResourceOverride class switches the default Dynamic locale switching On Mac, resources are part of bundles © 2011 Autodesk Heap Mismatch Issues Production AutoCAD uses “dll” C Runtime Lib (msvcrt) Other options are static libs (libc, libcmt) And debug libs (libcd, libcmtd, msvcrtd) And other MSVC versions (VS 2008) Some ARX APIs expect client to use same heap as acad. E.g., any API taking a non-const AcArray argument The array may be grown (i.e. reallocated) by acad © 2011 Autodesk Visual Studio Debug build should disable optimization But still should use release clib and mfc Enable PDB files for both release and debug Increase warning level to 3, make warnings fatal /W3 /WX Use .props files to <ImportGroup Label="PropertySheets"> <Import Project=“C:\MyProj\MyShared.props" /> standardize projects </ImportGroup> <ItemDefinitionGroup © 2011 Autodesk Project Types - Mac Use .dylib for DBX Use .bundle/.framework type for ARX Application framework is called COCOA Can use C++ or Objective C C++ uses gnu compiler Objective C very different from C++ // Objective C int n = [myObj getInt:nArg]; // C++ int n = myObj->getInt(nArg); © 2011 Autodesk Installing ARX Applications Recommend using AutoLoader Copy or install files to one of two special folders C:\Users\[login]\AppData\Roaming\Autodesk\ApplicationPlugins\MyApp.bundle C:\Program Files\Autodesk\ApplicationPlugins\MyApp.bundle Create a master XML file to describe the deployment Works with the app store (Exchange) Can use Microsoft MSI Well tested, integrated with Windows Can also do xcopy or unzip or use InstallShield or whatever © 2011 Autodesk Loading Applications - Manually arx load (arxload “myapp”) From AutoCAD command line Lisp function also callable from lisp scripts AppLoad dialog Drag and drop From explorer to AutoCAD window © 2011 Autodesk Loading Applications – on Startup Acad.rx text file Registry: Dialogs\Appload\Startup Acad.lsp Set up by AppLoad AcadDoc.lsp – invoked at dwg open Windows command line arg acad /ld MyApp.arx © 2011 Autodesk Loading Applications – on Demand ARX apps via registered command Applications\MyApp DBX enablers via dwg open Dwg contains custom object or entity App name attached to class via newAcRxClass() © 2011 Autodesk Commands Register your developer symbols to avoid name clashes http://www.autodesk.com/symbreg/index.htm . Create commands via acedAddCommand() Invoke commands via acedCommand() and acedCmd() These APIs use a “co-routine” stack mechanism on Windows #define ACRX_CMD_NONEWSTACK 0x00010000 // For internal use only Sending commands from modeless controls sendStringToExecute() is asynchronous © 2011 Autodesk Commands – and Fibers Fibers are used to support simultaneous stacks Also known as coroutines Similar to multi-threading, but fiber switches are controlled Not available on Mac. Microsoft has warned they’re going away too Issues with managed environments Use new acedCommandS() which bundles args with command © 2011 Autodesk Functions Use acedDefun() and acedRegFunc() to declare functions callable by Lisp Obtain resbuf list arg via acedGetArgs() Invoke lisp functions from C++ by calling acedInvoke() Use a registered developer symbol (RDS) on function names 4-letter prefix. Free and easy to register © 2011 Autodesk Programming Practices - Strings Use String Classes AcString, CString or std::wstring CString may not be portable to Mac Use Unicode wchar_t, not ansi char -define UNICODE=1 in project (CharacterSet=Unicode) When persisting to a file, consider UTF-8 More compact Easy to convert from utf-16 or utf-32 © 2011 Autodesk Programming Practices – XData and XRecords XData is older, simpler Less overhead Limited to 16k or 32k max size Easier to deal with in Lisp Resbuf list processing can get messy XRecords are AcDbObjects Usually owned by another Object’s Extension Dictionary Easier to locate than xdata because of dictionary key Unlimited size Resbufs can be awkward here too © 2011 Autodesk Programming Practices - Misc Be aware of dwg’s version GUID Uniquely identifies a dwg file – regenerated on every save Useful for associating dwgs to external databases Object handles normally never change Except during wblock * Use comments and asserts liberally It sounds obvious, but is usually not done © 2011 Autodesk Portability Tips Do not use long type Is 64 bits on Mac/gnu C++ Use IntPtr or other polymorphic types for variables that hold pointer and int vals Many Win32 APIs emulated in Mac ObjectARX Isolate U/I code into separate module from Dialogs and fancy U/I controls difficult to share Can use DCL as a crude portable U/I framework © 2011 Autodesk Error Handling – Out of Memory More likely in 32-bit environment Encourage customers to migrate to 64-bits Treated by AutoCAD as a fatal error Both AutoCAD and Windows may warn before it happens No point in checking for malloc or new returning NULL in your code Apps can temporarily override out-of-memory handling Use C++ set_new_handler() to intercept the event Check for NULL returned by new or malloc in that case Restore the previous new_handler() © 2011 Autodesk Error Handling – Opening and Closing Objects acdbOpen and upgradeOpen may fail Check results for eOk, handle failure gracefully Use SmartPointer classes for more reliable open/close dbobjptr.h, dbobjptr2.h – ReadableAcDbObject, WriteableAcDbObject Also help with objects on locked layers Don’t open objects for write unless you need to Don’t forget to close objects May lead to future failures to open Smart pointers can help with this too © 2011 Autodesk Error Handling – CERs Fatal Error Causes Access violations Internal fatal errors Out of memory Other unhandled exceptions Customer Error Reports Register your app so that Autodesk can contact you about CERs Your customers may email you the CER zip files for your inspection AutoCAD symbol server at symbols.autodesk.com/symbols © 2011 Autodesk Performance Tips – Dwg Files Opening dwg files _SH_DENYWR is lazy, but locks out writers _SH_DENYNO reads in whole file, allows other access kTryForReadShare attempts to do _SH_DENYWR, falls back to _SH_DENYNO For batch processing, consider separate processes per dwg Isolates the operations on each dwg No accumulated leaks Allows parallelism Requires communication between main process and slave processes Use shared memory, pipes, COM, or messages to communicate © 2011 Autodesk Performance Tips – Undo Consider partial undo recording for custom objects Consider disabling and re-enabling undo around some operations By default, entire object is filed out to undo filer E.g., if you are going to open a dwg, make some changes, save it and quit Undo file currently has a 2G logical limit File can be cleared by disabling and reenabling undo © 2011 Autodesk Performance Tips – Misc Don’t worry about micro coding tricks Compiler is very good at optimizing. Concentrate on code readability E.g.: *dest++ = *src++; Pre-allocate array space to avoid slow buffer growth AcArray<T>::setLogicalLength() or setPhysicalLength() std::vector<T>::resize() Consider linking with /delayload switch Will leave dlls out of memory until they are first called © 2011 Autodesk Custom Objects - Filing In dwgOutFields and dwgInFields, first file a version integer Use filerType() to decide whether all data needs to be filed Will come in handy during future versions E.g.: kPurgeFiler, kIdXlate filer only need to see ObjectIds Consider overriding cloneMeForDragging() to return false Avoids cloning during drag - good for very large entities Also override dragStatus(). All transformBy() calls up to dragStatus() are drag updates © 2011 Autodesk Links http://adn.autodesk.com/ (whitepapers, knowledge base, etc) http://usa.autodesk.com/support/documentation/ (product user guides) Arxdev.chm (ObjectARX Developers Guide) http://Wikihelp.autodesk.com/ - (articles on various products and technologies) http://through-the-interface.typepad.com/through_the_interface/ (.NET oriented) http://arxdummies.blogspot.com/ (simple arx tutorial) © 2011 Autodesk Thank you! Q&A © 2011 Autodesk Autodesk, AutoCAD* [*if/when mentioned in the pertinent material, followed by an alphabetical list of all other trademarks mentioned in the material] are registered trademarks or trademarks of Autodesk, Inc., and/or its subsidiaries and/or affiliates in the USA and/or other countries. All other brand names, product names, or trademarks belong to their respective holders. Autodesk reserves the right to alter product and services offerings, and specifications and pricing at any time without notice, and is not responsible for typographical or graphical errors that may appear in this document. © 2011 Autodesk, Inc. All rights reserved. © 2011 Autodesk