ManuSoft

  • Full Screen
  • Wide Screen
  • Narrow Screen
  • Increase font size
  • Default font size
  • Decrease font size

Using VC 7 to Build For AutoCAD 2000/2002

Print

With the advent of AutoCAD 2004 and Visual Studio .NET (aka Visual Studio 2002), ObjectARX programmers are again faced with the task of moving from an older version of a compiler (VC6) to a newer version (VC7). Rather than maintain two versions of compilers and two versions of projects for supporting both AutoCAD 2000/2002 and the new AutoCAD 2004, it makes sense to use only the newest IDE to support *all* target AutoCAD platforms.

You can easily add build configurations in to your project VC7 so that the same project builds ObjectARX modules for both AutoCAD 2000/2002, and AutoCAD 2004, but the trick is to force VC7 to build your AutoCAD 2000/2002 target with the correct headers and libraries. In addition, you have to make sure your source code compiles correctly with both old and new ObjectARX SDK versions. This will likely require some conditional compilation if your code uses parts of the SDK that have been modified in ObjectARX 2004.

Following are some tips for successfully building ObjectARX 2000/2002 projects in VC7.

  • Don't put ObjectARX SDK folders into your global settings. Use the procedure outlined here to define search paths in your project properties using environment variables.
  • Disable 'Edit and Continue' in all your AutoCAD 2000/2002 target builds. Go to project properties C/C++->General and set 'Debug Information Format' to anything except 'Program Database for Edit & Continue' (normally Debug builds should use 'Program Database' and Release builds should use 'Disabled'). Next, go to Linker->General and set 'Enable Incremental Linking' to 'No'. If you leave this option enabled, the linker pads the output file with uninitialized empty space, which causes the module validity checking in AutoCAD 2002 to choke on the file and fail to load it. Note that if you link to any libraries that were built with 'Program Database for Edit & Continue' enabled, the linker will warn that the /EDITANDCONTINUE switch was ignored. Just ignore the warning, or rebuild the offending library.
  • In your project properties, specify explicit paths for include files and library files to the correct version of ObjectARX and the VC6 version of the C/C++ runtime. Following is an example that shows the settings for include directories (if this project used MFC, it would also list $(MSVC6)\MFC\Include). You must do the same thing in settings under Linker->General for 'Additional Library Directories', except you must specify the library directory (e.g. $(ARX2000)\Lib and $(MSVC6)\Lib).
  • VC7 includes a new feature that inserts runtime buffer overrun checks into your Release builds by default. This runtime check uses a VC7 runtime library function that is not available in VC6, so you need to disable the feature when linking with VC6 libraries. To disable it, go to project properties and select the desired configurations, then navigate to settings for C/C++->Code Generation. Change the setting for 'Buffer Security Check' to 'No'*.
    Changing this setting prevents the following linker errors:

error LNK2019: unresolved external symbol ___security_cookie referenced in...
error LNK2019: unresolved external symbol @__security_check_cookie@4 referenced in...

* The current Microsoft Platform SDK now includes a separate library that provides implementations for these functions. Just link to bufferoverflowu.lib to resolve them correctly, with no need to turn off this new compiler feature (see KB894573).  

  • In VC6, casting a floating point number to a long caused the compiler to generate a call to a hidden library function named _ftol. VC7 generates a call to _ftol2 (obviously the implementation of this function changed, so the name was changed to prevent version clashes). If your source code includes a cast from double to long types, VC7 will generate a call to _ftol2, and the following linker error will result:

error LNK2001: unresolved external symbol __ftol2

Resolve this error by placing the following in one of your .cpp files (StdAfx.cpp, for example):

#if (_MSC_VER >= 1300) && (_MSC_VER < 1400) && (WINVER < 0x0500)
//VC7 or 7.1, building with pre-VC7 runtime libraries
extern "C" long _ftol( double ); //defined by VC6 C libs
extern "C" long _ftol2( double dblSource ) { return _ftol( dblSource ); }
#endif
  • If you use the /DELAYLOAD linker feature to delay-load implicitly linked DLLs, you will encounter the following linker errors when linking to VC6 libraries:

error LNK2001: unresolved external symbol ___delayLoadHelper2@8
error LNK2001: unresolved external symbol ___delayLoadHelper2@8

These errors are caused by a change in the delay load helper function in VC7, that was in turn the result of a change in the delay load import descriptor that the linker embeds inside the image file. Microsoft renamed the function to prevent the possibility of the new format produced by the VC7 linker being linked with the old helper function (that expects the old format). Unfortunately, AutoCAD's [brain dead] module validity testing chokes on the new delay load import descriptor format.

The solution to this problem is twofold: first make the linker happy by linking to the new VC7 delayimp.lib; second, postprocess the linker-created .arx module to hide the delay load import descriptor so AutoCAD can't choke on it.

  1. The first part of the solution involves renaming the VC6 delayimp.lib file* so VC7 doesn't find that one, and uses it's own version instead. The file is located in VC98\Lib. I renamed mine to VC6.delayimp.lib.
    * Arnold Eibel sent me an email with a better solution: instead of renaming the VC6 delayimp.lib, just specify an explicit path to the correct file to use. Arnold's suggestion is to use "$(VcInstallDir)lib\delayimp.lib", thus making the path portable to future versions of VC.
  2. The second part of the solution is not as difficult as it sounds. I made a command line utility to remove the delay load import directory from the file. This won't affect the file's operation at all, but it will prevent PE file viewers (such as Dependency Walker) from being aware of the delay loaded dependencies. Simply download the utility (96k) and place it somewhere in your VC7 support path (i.e. VC7\Bin) or better yet put it in its own folder and add the new folder to the path for executables in VC7 global options. Next, add a post build step to run the conversion utility on the target module. Do this in settings for Build Events->Post-Build Event, and add this to the 'Command Line' setting:
    HideDelayLoadImports.exe "$(TargetPath)"

These are the problems I have encountered so far in my conversion process. As I encounter new problems, I will add my solutions to this list of tips. If you have additions or comments, please don't hesitate to contact me via email (but please understand that sometimes I can't reply to every email I receive).

You are here: Resources ObjectARX Tips and Tricks VC 7 for ObjectARX 2000