This topic outlines items that you should be aware of when writing ObjectARX applications.
Developers should opt out of the Customer Involvement Program to prevent causing such a crash when AutoCAD is run from the debugger.
By default, .NET assembly files cannot be used over a network. They can only be loaded into AutoCAD over a network if special permissions are granted to them.
For every new release of AutoCAD-based products and RealDWG™ host applications, the registry number will be incremented to ensure continued side-by-side installation support. The major build number will be incremented only when APIs are introduced that are incompatible with the previous release. The minor build number will be incremented when the release is binary compatible with the previous release.
The ObjectARX/ObjectDBX loading mechanism inspects only the registry section that matches the version of the host application. It will not look in multiple locations. Therefore, if your product needs to support demand loading for several different versions, you must add your demand load entries to the registry section for each of those versions.
Ideally, a change of registry number should have no impact on your application's code, because this number should not be hard-coded anywhere. Instead, if your application needs to know the correct registry key at runtime, you should use the appropriate APIs. ObjectARX applications (in other words, those with an .arx extension) should use the AcDbHostApplicationServices::getUserProductRegistryRootKey() and AcDbHostApplicationServices::getMachineProductRegistryRootKey() function or the acrxProductKey() global function. ObjectDBX modules (in other words, those with a .dbx extension) should use the acrxObjectDBXRegistryKey() global function to get the correct registry key. These functions always return the correct registry key for the host application's version.
Classes derived from AcDbBlockReference cannot append attributes. This is by design. A call to appendAttribute() on an object of an AcDbBlockReference-derived class will result in the error eIllegalEntityType.
Objects derived from CAdUiDockControlBar, which includes palette sets and tool palette sets, can write a registry key that will ensure safe operation with workspaces and cause them to be displayed in the Customize User Interface dialog box. See "Registering Objects Derived from CAdUiDockControlBar" in the ObjectARX Developer's Guide for more information.
In the ownership hierarchies for your custom objects, be sure to call setOwnerId() to properly establish every object's owner backpointer. A future version of AutoCAD/ObjectDBX may cease writing objects with NULL owner IDs in incremental saves.
The ADN website no longer includes an object enabler section. Developers should post their object enablers on their own web sites and let customers know where they are available.
Dimension definition points and text position are all subject to the layout requirements of the dimension. With any of the following functions, the position passed in may be changed to fit within the layout needs of the dimension as determined by the dimension type and the current dimvar settings.
AcDbDimension::setTextPosition() AcDbAlignedDimension::setDimLinePoint() AcDbRotatedDimension::setDimLinePoint() AcDb3PointAngularDimension::setArcPoint() AcDb2LineAngularDimension::setArcPoint()
For example when DIMFIT = 3, for radial dimensions with the definition points such that the radial line is less than or equal to fifteen degrees from the X-axis, the text position's X coordinate can be set, but the Y coordinate will always be adjusted to locate the text along the radial line of the dimension.
The acedCommand() works in two basic contexts: when operating on the RQXLOAD and RQSUBR request codes. In ObjectARX, however, it does not work for the ObjectARX application message AcRx::kLoadDwgMsg, which is the ObjectARX equivalent of RQXLOAD. It works fine for the message AcRx::kInvkSubr, which is equivalent to RQSUBR.
It is important to many applications to execute a few AutoCAD commands at the beginning of every drawing edit session. This can be accomplished by queuing up AutoLISP expressions, including use of the (command) function, using ads_queueexpr(), for execution during the edit session initialization, after (s::startup) has been executed.
Note that the queued expressions are not executed during the call to ads_queueexpr(). They will occur after your application has returned from its kLoadDwgMsg message invocation of acrxEntryPoint().
When using ads_queueexpr(), the entered string must be fully expanded, with outer parentheses. Whatever was previously passed in as resbuf chains must be converted to ASCII to use this mechanism.
Multiple calls to ads_queueexpr() from the kLoadDwgMsg callback are perfectly acceptable. They get queued up in the order of the calls.
Do not use ads_queueexpr() in any other context. To do so will have unpredictable results, and may even be damaging, because the queue may not be looked at until active AutoLISP evaluations, MENU items, and/or SCRIPT executions are all quiescent. Use this function sparingly, as it will be removed as soon as the original design can be implemented.
The header files acdb.h and dbidar.h contain an #ifdef section which selects a header to #include based on ACAD_OBJID_INLINE_INTERNAL. Applications should never #define this value. There are parallel headers for the lightweight ID types, some of which are for internal AutoCAD use only. Applications that attempt to #define ACAD_OBJID_INLINE_INTERNAL will not compile successfully.
When calling methods that return non-const string pointers (for example, AcDbSymbolTable::getName(char&* pName)), you should free the memory occupied by the returned string. For example:
// The getName() call should be followed by a call to acutDelString(pLtName);pLtTableRcd->getName(pLtName); // ... other code acutDelString(pLtName);
Note that some of the ObjectARX sample files are missing calls to free the memory, so they will exhibit memory leaks. When using the samples in your own code, make sure to free the memory properly.
If you spawn multiple threads in your application, make sure that no more than one of the threads at a time invokes anything in the ObjectARX system.
Certain interactions between transactions, the UNDO command, and the Object Property Toolbar (OPT) can put AutoCAD in an unstable condition. To avoid such situations, your ObjectARX application should always remove the pickfirst selection prior to aborting transactions, as shown here:
acedSSSetFirst(NULL, NULL); actrTransactionManager->abortTransaction();
Tabbed dialog boxes should use the base classes defined in the acui24.lib MFC extension DLL library. Do not use the MFC classes CPropertySheet and CPropertyPage. Use CAcUiTabMainDialog and CAcUiTabChildDialog instead. See the ObjectARX Developer's Guide and ObjectARX Reference for details.
Using the __declspec(dllimport) construct on a class exported to other applications can cause vtables to reside in all DLLs that instantiate that class. If any of these instantiating DLLs is unloaded, all instances created by that DLL become invalid. Subsequent attempts to access virtual functions on these invalid instances triggers a memory fault.
Consequently, the only safe way to use this directive with classes derived from AcDbObject, for example, is to mandate that no application that instantiates the class may be unloadable. To enforce this mandate, you must either document it clearly and visibly, or supply a pseudo-constructor that resides in a DLL or application that cannot be unloaded. The best policy is to avoid using this construct altogether.
The only exception to this warning applies if the class exports a static data member. In this case, you must use __declspec(dllimport) on that data member only, but you should avoid applying the construct to the entire class. Exporting static data members is not recommended.
This warning applies only to __declspec(dllimport). It does not apply to __declspec(dllexport).
The recommended usage is as follows:
#pragma warning( disable: 4275 4251 ) #ifdef POLYSAMP #define DLLIMPEXP __declspec( dllexport ) #else #define DLLIMPEXP #endif // The "DLLIMPEXP" is only required for exporting a poly API or using // the exported API. It is not necessary for any custom classes that // are not exporting an API of their own. // class DLLIMPEXP AsdkPoly: public AcDbCurve { public: ACRX_DECLARE_MEMBERS(AsdkPoly); //***************************************************************** // Constructors and destructor //*****************************************************************
When building debug versions of ObjectARX applications, you may see LNK4099 linker warnings similar to the following:
rxapi.lib(libinit.obj) : warning LNK4099: PDB "acdbhdr.pdb" was not found with "..\..\..\lib\rxapi.lib" or at "C:\ObjectARX\samples\editor\mfcsamps\dynamic_dg\Debug\acdbhdr.pdb"; linking object as if no debug info
The warning occurs because ObjectARX libraries are built with PDB files that are not shipped with the ObjectARX SDK. It is safe to ignore these warnings.
If you include any of the standard C++ headers while the _DEBUG preprocessor symbol is defined, then the debug C++ runtime is forced via pragmas. (Look at use_ansi.h in Visual C++.) You don't want to use the debug C++ runtime in an ObjectARX application.
To avoid this, apply the following workaround:
#ifdef _DEBUG #undef _DEBUG #endif
AutoCAD may occasionally demand load an application that defines a class, even when there is no object of that class in the DWG or DXF file being loaded. If you observe this and wish to prevent the unnecessary demand loading of .dbx and .arx applications, simply save the drawing in either the DWG or DXF format and then reopen the file. This procedure can be done with or without the application available.
Use a complete open, followed by a full save, before reloading the file.
In previous releases, the proxy graphics DWG data structure could not handle the complexity of the polyline (pline) primitive. This limitation has been addressed as of AutoCAD 2004. As a result, the AcGiGeometry::pline() function now supports the proxy graphics context.