Capacidades Ampliadas Utilizando AutoCAD .NET ObjectARX
Capacidades Ampliadas Utilizando AutoCAD .NET ObjectARX
Capacidades Ampliadas Utilizando AutoCAD .NET ObjectARX
Learning Objectives
• Lean how to extend AutoCAD .NET managed capability.
• Discover exposed functions in AutoCAD files that can be imported to managed code.
• Get the structure of the exported functions and import them into managed code.
• Discover Platform Invoke (P/Invoke).
Description
This instructional demonstration will teach AutoCAD.NET API software developers how to
extend the managed ObjectARX libraries to use hidden functionality. The standard AutoCAD
.NET managed libraries provide extensive support, but there are some capabilities that aren’t
wrapped into the managed libraries. In this instructional demonstration, we’ll discuss ways to
work with AutoCAD software files and ObjectARX libraries. The demonstration will show how to
use available managed .NET applications. We will also provide sample code that you can
modify and use in your applications.
Speaker(s)
James Johnson has worked with CAD products for more than 30 years in many positions, from
being a CAD drafter to writing automation applications. In current position, James does CAD
integration for a document management system. In previous positions, used RealDWG® to
write custom automation to create AutoCAD drawings of industrial kitchen equipment, and has
worked at resellers of Autodesk products in software development. James has taught AutoCAD
software and AutoCAD Microsoft Visual Basic software classes at resellers, and was a CAD
instructor at community colleges.
Todd Schmoock is a graduate of Delaware Valley University in Doylestown, Pa. He spent time
as a documentation specialist/designer at Honeywell, Inc. where he worked on several
government contracts requiring strict drafting and design documentation in accordance with
government standards. He has also worked in the technical ceramic, elevator, and specialty gas
industries designing equipment for each of these fields. Todd joined Synergis as a Solutions
Engineer where he provides assistance to customers through training, consulting, helpdesk
support, as well as providing pre-sales support. Todd is an Autodesk Inventor Certified Expert
and a Manufacturing Solutions Implementation Certified Expert.
Page 1
Introduction
Programming environments for .NET (Microsoft® .net Framework) and the ObjectARX®
libraries, provide object-oriented C++, C# and VB .NET application programming interfaces for
developers to customize and extend AutoCAD®. These libraries provide direct access to the
AutoCAD® database, graphics system, and native command definition. Some capabilities are
not exposed with .NET ObjectARX® and can be exposed by using Platform Invoke (P/Invoke) to
make exported capabilities in AutoCAD® and native ObjectARX® available in managed .NET
applications. This document will show some ways as to how to find exported functionality and
then make it available. The requirements for the projects discussed in this class and document
require Visual Studio, AutoCAD and ObjectARX libraries.
Additionally, a brief discussion on using AutoCAD® ObjectARX wizards to create projects from
predefined templates.
Note: This is an intermediate class, assumption is made that attendees have a basic
understanding of basic programming concepts (including some .NET programming), and have
experience with customizing AutoCAD®. Knowing how to create a .NET project that creates a
DLL to be loaded into AutoCAD® is helpful, but is briefly covered later in this handout.
There are several ways to extend managed code by building your own API Class Library DLL’s
that can then be referenced into your applications. These DLL’s can be built from C#, VB.NET
and or C++/CLI projects. The classes and methods can then be exposed and used in the same
way that the AutoCAD DLL’s are referenced and used.
Extension Methods
Extension methods allow the creation of methods on an existing “Type” creating the illusion of
new methods, even when a class is compiled outside of the current assembly and cannot be
changed. With extension methods developers can augment the “Type” with new methods to
provide their own specialized implementation. Extension methods are defined in static classes
as static methods. In C#, extension methods are indicated by the “this” modifier which must be
applied to the first parameter of the extension method.
Page 2
Extension Methods (continued)
return btr;
}
return dbTxt;
}
The type of the first parameter of an extension method (with the “this” modifier) indicates what
type the extension will be applied.
Extension methods are resolved at compile-time based on which extension methods are in
scope. When a namespace is imported with C#’s using statement or VB’s Import statement, all
extension methods that are defined by static classes for that namespace are brought into scope.
Many of the LINQ standard query operators are extension methods in the System.Linq
namespace, these extension methods extend IEnumerable<T> and IQueryable<T>. All but a
few (e.g. OfType) of the standard query operators extend from the IEnumerable<T> interface,
which means that all IEnumerable<T> types get the standard query operators by adding the
using statement in C#: using System.Linq;
Extension methods will be seen and can be selected using an object of the extended TYPE.
They will show in IntelliSense popup with an arrow icon.
Page 3
Extension Methods (continued)
Page 4
Discover exported functions in AutoCAD® files that can be imported
to managed code.
The inspiration behind submitting this class was due to that in AutoCAD 2016 a new underlay
type was added to make references to Navisworks files and the application that I was working
on at the time needed a way to get the full path and name of the new Navisworks object. The
problem is that the object was not exposed in the AutoCAD/RealDWG .NET ObjectARX API.
Since there is minimum documentation on this new object or any objects for it in the “Object
Browser” of the referenced DLL’s, I decided to look into if it could be found in a different way
and found mangled functions exported in the new ObjectDBX vertical custom entity file
“AcBIMUnderlayDbx.dbx”. Continued looking into it and found a way to get that path which will
be used in this document for reference.
The following is a way to find the object and its full path and name using P/Invoke.
Contents of “findapi.bat”:
@echo off
if "%1" == goto usage
:normal
for %%i IN (*.exe *.dll *.arx *.dbx *.crx) DO dumpbin /exports %%i | findstr "%%i %1"
goto end
:usage
echo findapi "function name"
:end
Page 5
Copied the above findapi.bat to the AutoCAD folder and ran in a command
window.
After copying the findapi.bat file to the AutoCAD folder it was now time to run it and collect the
output into a text file. Start VS2017developer command window which has the path to dumpbin
preset, changed to the AutoCAD folder and then ran the findapi.bat with a search string and
output file name.
This shows that the output type of the ‘getName’ function is of a type ‘AcString’ and in .NET
there is no direct conversion of that type to a System.String type. After looking at several
different possible ways to convert from ‘AcString’ to System.String it appeared that the easiest
would be to do the P/Invoke in a C++/CLI ObjectARX project and then get it into the C# project
that required getting the name of the Navisworks underlay object.
In the Name.txt file created from running findapi.txt, found the following:
The text file contains the mangled representation of the exported functions in the files. The ones
of interest here were the ‘getName’ functions that are exported in the ‘AcBIMUnderlatDbx.dbx’
file.
?getName@AcDbNavisworksModel@@QEBA?AW4ErrorStatus@Acad@@AEAVAcString@@@Z
Page 6
Get the structure of the exported functions and import them into
managed code.
Once “dumpbin.exe” has ran through the findapi.bat file referenced above the output text file
has mangled representations of the functions that are exported in the files that are scanned.
These mangled representations are not always easily understood, but there is a system tool that
will un-mangle that representation and produce a representation that more resembles
something that would represent code, showing the arguments and return types.
Take the mangled string and use “undname.exe” to get the methods structure
This gives an ‘un-mangled’ representation that helps with understanding the structure of the
function in somewhat of a code representation to assist in creating the P/Invoke entry.
This shows that the output type of the ‘getName’ function is of a type ‘AcString’ and in .NET
there is no direct conversion of that type to a System.String type. After looking at several
different possible ways to convert from ‘AcString’ to System.String it appeared that the easiest
would be to do the P/Invoke in a C++/CLI ObjectARX project and then get it into the C# project
that required getting the name of the Navisworks underlay object.
Page 7
Discover Platform Invoke (P/Invoke)
P/Invoke is used by .NET languages to call unmanaged functions in DLLs. Commonly used to call
Windows API functions that are not available in the .NET Framework, other functions provided in
DLL’s found in AutoCAD and other Third-Party applications can be exposed and called.
Now to construct this information in a useable form it gets added to the application using
Platform Invoke (P/Invoke) by using DLLImport attribute to load and specify the structure of the
method.
Created a simple C++/CLI ObjectARX project using the ObjectARX wizards. This wizard created
the project and files which only required minor changes to have a DLL that could then be
referenced into other .NET applications.
In the C++/CLI to do the P/Invoke is accomplished very similar to how it is done in C# projects.
The ‘AcString’ object was easily converted to ‘System::String’ object in the C++/CLI project.
Page 8
Then called from a C# assembly that references the C++/CLI DLL
Looking at objects in the drawing and getting their type allows filtering the Navisworks undelay
object. The object is by default an “ImpDBObject” and then further its RXClass type is
“AcDbNavisworksModel”.
Once the type is found then the call is made to the C++/CLI referenced DLL to return the value
Note:
Using the C++/CLI ObjectARX to convert the return values of AcString to System::String is just
an example of how creating ObjectARX classes can be used to extend the .NET API.
In addition to exposing simple P/Invoke functions to .NET, a C++/CLI ObjectARX DLL can be
used to expose other native ObjectARX code that you may have by exposing those methods to
.NET applications.
Page 9
Additional uses of Platform Invoke (P/Invoke)
Page 10
AutoCAD functions…
ObjectARX® functions that are not included in the AutoCAD® .NET assemblies can be run by
using platform invoke (P/Invoke). Several useful functions to use with AutoLISP® are
acedInvoke, acedPutSym and acedGetSym. The acedInvoke function allows running an
AutoLISP® function from .NET applications.
Page 11
AutoLISP® function from .NET applications.
Update: In AutoCAD 2017 and newer ObjectARX applications instead of P/Invoke use
“Application.Invoke(args)” where “args” is a ResultBuffer and return value is also a
ResultBuffer.
The acedPutSym and acedGetSym functions allow getting and changing AutoLISP® variable
values.
Page 12
Executing AutoCAD Commands
In previous versions of AutoCAD .NET applications developers would often need to execute a
command in the AutoCAD session.
From AutoCAD 2015 and newer the preferred way to execute a command is by using the Editor
and use the Command or CommandAsync methods:
Page 13
Invoking AutoLISP from .NET
AutoLISP functions can be invoked from within a .NET application.
The following is an AutoLISP call that with AutoCAD Electrical will output a BOM report to an
XML file:
(c:wd_bompnlr (list 1 1 "" 127 0 "XML" 0 "c:\\report\\lispBompnl.xml" nil))
A ResultBuffer is built and then Invoked which returns a new ResultBuffer that contains the
results of invoking the AutoLISP function.
The ResultBuffer class is the .NET equivalence of the ObjectARX “resbuf struct”, it provides a
container for AutoCAD specific data.
In the example above the ResultBuffer is populated with an array “TypedValue” objects that
reflect the requirements for the AutoLISP function.
Page 14
Invoking .NET from AutoLISP
AutoLISP functions are defined with .NET by using the “LispFunction” attribute, similar to how
AutoCAD commands are created with the “CommandMethod” attribute.
In AutoCAD:
Page 15
Notes
Download “ObjectARX libraries” and “ObjectARX Wizards” at:
http://usa.autodesk.com/adsk/servlet/index?id=1911627&siteID=123112
When installing the ObjectARX Wizards they need to be installed as an ADMIN to properly
install and allow new projects to be created.
The easiest way is to run the Visual Studio command window as an administrator:
Then browse to the location of the unzipped file and run the installer:
Page 16
Useful Links discussing using P/Invoke
http://through-the-interface.typepad.com/through_the_interface/2008/08/using-the-pinvo.html
http://adndevblog.typepad.com/autocad/2012/04/synchronously-send-and-wait-for-commands-
in-autocad-using-c-net.html
http://www.quuxsoft.com/Programming/PInvoke.aspx
https://msdn.microsoft.com/en-us/library/ac7ay120(v=vs.100).aspx
http://www.pinvoke.net
Page 17