Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Taking a snapshot of the AutoCAD model (take 2) | Main | Adding a new annotation scale in AutoCAD using .NET »

    April 20, 2007

    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.

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e200d8341e065853ef

    Listed below are links to weblogs that reference Loading the right version of an ObjectARX module into 32- or 64-bit AutoCAD:

    Comments

    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))
    )

    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.

    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)
    )
    )

    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).

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

    Perfect!

    Kean

    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
    )
    )

    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

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search