Loading the right version of an ObjectARX module into 32- or 64-bit AutoCAD

This question has come in from a number of developers...

How can I tell when my application is running inside a 64-bit version of AutoCAD?

As mentioned in this previous post, AutoCAD 2008 installs as native 64-bit binaries on a supported 64-bit OS, just as 32-bit binaries get installed on a supported 32-bit OS.

A minor complication is that certain of our AutoCAD-based products do not yet have native 64-bit versions. Our Engineering teams are working on this, but in the meantime, your application might well be working inside a 32-bit Autodesk product on a 64-bit OS.

So how do we know whether we're on a 32- or 64-bit platform (i.e. AutoCAD)?

The ideal would be to have a simple system variable (just like we have ACADVER for the version of AutoCAD), which can be queried from any environment. Unfortunately this has not (as yet) been provided, so we have to look for another approach, for now.

The good news is that .NET applications generally shouldn't care - the same binary will work on both 32- and 64-bit platforms. The same for LISP, but then people often use LISP loaders to load ObjectARX modules - which most certainly do care - so my feeling is that this problem will most commonly be faced from LISP.

Before talking about getting the information from LISP, let's talk a little about ObjectARX, first. ObjectARX modules are built specifically as 32- or 64-bit versions. The version you load will depend on the host executable (the AutoCAD platform) you're working in, not on the OS. A 32-bit module will simply not load in a 64-bit version AutoCAD and vice-versa. The way most professional developers make sure the right version of their module is loaded, is to set up demand-loading keys appropriately from their installers, which AutoCAD uses to locate the appropriate modules and load them.

A module doesn't usually need to know whether it is 32- or 64-bit (and with polymorphic types in ObjectARX you should be able to build both versions off the same source code). That said - you might want to enable certain memory-intensive operations from your 64-bit modules but not from your 32-bit versions (for example), so one way is simply to declare a pointer and check its size (thanks to Gopinath Taget, from our DevTech team in San Rafael, for proposing this solution):

Adesk::IntPtr ptr;

int ptrSize = sizeof( ptr );

If ptrSize is 4, then you're in a 32-bit module - if ptrSize is 8, you're in a 64-bit module.

This could clearly also be exposed as a LISP-callable function (using acedDefun()), which is a solution for people who create their own ObjectARX modules but clearly not viable for people who don't.

So now back to our common scenario of people using LISP to load the correct version of an ObjectARX module: in the absence of a handy system variable, what do we do?

I thought about this for a while, and booted around some strange ideas such as using COM from LISP to query file attributes from AutoCAD binaries (yeech), and eventually decided that the best approach was simply to try to load a module, and if it fails, try a 64-bit specific name.

Here's the technique - you would use this function as a replacement for (arxload "myapp"):

(defun myarxload (fn / fn64)

  ;(princ (strcat "\nLoading " fn))

  (if

    (vl-catch-all-error-p

      (vl-catch-all-apply 'arxload (list fn))

    )

    (progn

      (setq fn64 (strcat fn "x64"))

      ;(princ (strcat "\nLoading " fn64))

      (if (findfile fn64)

        (arxload fn64)

      )

    )

  )

  (princ)

)

This code assumes a few things...

  • We pass in the module name without the extension (as we append "x64" to the filename)
  • We have used "x64" as a suffix for 64-bit versions of our modules (e.g. "AdskMyAppx64.arx")
    • I'm not aware of any convention for this... we simply use the same module names inside AutoCAD (which removes the need for code such as this, in any case)

I'd be very interested to hear the experiences and suggestions of readers of this blog on the subject. This topic has come up a few times and perhaps more of you have comments that would help.

11 responses to “Loading the right version of an ObjectARX module into 32- or 64-bit AutoCAD”

  1. The environmental variable PROCESSOR_ARCHITECTURE will tell you whether your running as x64 or x86 ("x86" if your running under Wow64), so the following should work

    (defun myarxload (fn fn64)
    (if (= (getenv "PROCESSOR_ARCHITECTURE") "AMD64")
    (arxload fn64)
    (arxload fn))
    )

  2. Thanks, Wyatt - that's helpful information.

    This assumes the AutoCAD binaries will match the OS platform, which is true for AutoCAD 2008, but not for AutoCAD Architecture 2008 or AutoCAD Map 3D 2008 (for instance), where 32-bit versions will install on 64-bit versions of Windows.

    But yes - this defeinitely helps for vanilla AutoCAD.

  3. I don't have 64 bit to check,
    but if Autodesk have renamed the Visual Lisp Arx for 64 bit as you suggest ...
    perhaps this will suit.

    (DEFUN myarxload (fn fn64)
    (VL-LOAD-COM)
    (IF (VL-POSITION "vlx64.arx" (ARX))
    (ARXLOAD fn64)
    (ARXLOAD fn)
    )
    )

  4. Thanks for the suggestion, Kerry.

    I'm fairly sure we're not renaming our 64-bit modules (going from the names of the libraries in the 64-bit ObjectARX SDK - I too haven't yet used the 64-bit version of AutoCAD).

  5. If you are running as a 32bit process on 64bit windows (via Wow64), (getenv "PROCESSOR_ARCHITECTURE") will return "x86".

  6. Perfect!

    Kean

  7. During a forum conversation with a few other developers we came up with another solution:

    Since the ActiveX Object ID on the 64 bit platform is actually larger than the 32 bit version the following lisp code should work.

    (defun acad64bit-p ()
    (vl-load-com)
    (>
    (strlen
    (vl-prin1-to-string
    (vlax-get-acad-object)
    )
    )
    40
    )
    )

  8. Kean Walmsley Avatar

    One other point, for completeness... it seems you can get the OS using (getvar "PLATFORM"), although clearly you'll need another technique (such as (getenv "PROCESSOR_ARCHITECTURE")) to find out whether the AutoCAD-based product is running as a 32- or 64-bit process.

    Kean

  9. If you have an Acad 32bit running on a 64bit-machine you need to load the 32bit version of your ARX. So testing if your machine is 64 bit is not bulletproof. You need to check that Acad is 32 or 64bit.
    In Acad 64bit, the SysVar "Platform" generates
    something like this :
    "Microsoft Windows NT Version 6.1 (x64)", in Acad 32bit this should be : "Microsoft Windows NT Version 6.1 (x86)"
    (vl-string-search "x86" (getvar "platform") should do the trick.

    Bruno

  10. AutoCAD 32-bit versions (at least from 2009) will not install (and are not supported) on 64-bit Operating Systems.

    That said, this situation doesn't necessarily hold for our AutoCAD-based vertical applications, so it's true that more care must be taken there.

    Kean

  11. The search for elegance is sometimes overrated. There is a facier way (I found one on the internet when I was at another company) - but this stuff from Kean is a good method, and works (with a little tweaking).

    Thanks for the idea man.

    (defun arxloader (fn fn64 /)
    ;(princ (strcat "\nLoading " fn))
    (if
    (vl-catch-all-error-p
    (vl-catch-all-apply 'arxload (list fn))
    )
    (progn
    ;(setq fn64 (strcat fn "x64"))
    ;(princ (strcat "\nLoading " fn64))
    (if (findfile fn64)
    (arxload fn64)
    )
    )
    )
    (princ)
    )

Leave a Reply to Jon Cancel reply

Your email address will not be published. Required fields are marked *