AutoCAD Services & Support

Pass functions and variables between AutoLISP®, Visual LISP™, and external ObjectARX® applications

Published date: 2003-Apr-30
ID: TS67231

Applies to:
AutoCAD® Release 14

Issue

This solution explains how to pass variables and functions between AutoLISP®, Visual LISP™, and external ObjectARX® applications created with the Visual LISP compiler. It also expands on the use of key Visual LISP functions related to this topic, and the use and creation of Externally Defined Function files (XDFs).

Solution

The Three Environments

The first concept on which this solution is developed is that global and local variables or functions defined in any one of the three applications in Figure 1 are initially available only in that particular application's environment. Furthermore, it is important to understand that for every Visual LISP compiled ObjectARX application that is loaded into AutoCAD® software, a new and separate environment is created. However, because this ObjectARX application probably does not have an Integrated Development Environment (IDE), access to and manipulation of its environment will be limited. It is the IDE that allows you to write and debug your code.

In general, any externally defined variable or function that you want an application to recognize must be copied from the owner's environment to the target environment. For variables, you will need make a copy of the variable in the target environment. For functions, you will be creating an entry point for the ObjectARX application in the target environment after which you can access your pre-exposed functions.

Note: Unless otherwise noted, future references to ObjectARX applications in this document should be understood as ObjectARX compiled LISP applications created using Visual LISP's Application wizard.

Figure 1 - This diagram illustrates how AutoLISP and Visual LISP environments have a separate memory space. You must follow specific procedures discussed in this document in order to "share" variables and functions.

Visual LISP and your ObjectARX Applications

It is through the use of the Visual LISP expanded function library that you will pass variables and functions between applications. AutoLISP itself does not provide the necessary tools to accomplish these tasks. Whether you are developing in Visual LISP or using an ObjectARX application, the tools are the same. The only functional difference between the ObjectARX applications that you will be creating with Visual LISP and Visual LISP itself is the lack of an IDE. Therefore, techniques for managing connections between AutoLISP and Visual LISP are the same between AutoLISP and your ObjectARX applications unless otherwise noted. With this understanding, we are able to move on to the tools that Visual LISP provides for passing variables and functions.

Passing Variables

There are two functions that are used for passing variables between the Visual LISP environment and the AutoLISP environment. They are vlisp-import-symbol and vlisp-export-symbol. Although the functions names imply the transference of variables, what they actually do is replicate the variable in the target environment. The syntax is as follows:

(vlisp-import-symbol 'myVar)

This creates a variable named myVar in the Visual LISP environment and assigns it the same value it has in the AutoLISP environment. It returns the value of the variable:

(vlisp-export-symbol 'myVar)

This creates a variable named myVar in the AutoLISP environment and assigns it the same value it has in the Visual LISP environment. It returns the value of the variable. These functions will not work directly between Visual LISP and your ObjectARX applications. For example, if you want to copy a variable from an ObjectARX application to Visual LISP (vlide.arx), that ObjectARX application must first export the variable to AutoLISP, at which point you can import the variable from AutoLISP to Visual LISP.

If you would like to import a variable from AutoLISP as a local variable, the vlisp-import-symbol expression must be included inside the intended function and the variable name must be included in the function's argument list. For example:

(defun foo (/ *a*)
(vlisp-import-symbol ?*a*)
(princ *a*)
)

Furthermore, these functions do not create any link between the AutoLISP environment and the Visual LISP environment. If the value of the variable changes in one of the environments, it must be re-exported or re-imported to update the value in the other environment.

Passing Functions

Before we move on to examining how to pass functions between environments, we will need to clarify some concepts surrounding this topic. In Visual LISP, to pass a function from one environment to another is a two-step process. You must expose the function you intend to call and register the ObjectARX application's entry point in the target environment.

At an elementary level, the application's entry point consists of the name of the ObjectARX application and a list of its exposed functions. Once the application is loaded and the necessary entry point registered, you can call your externally defined functions.

Note: Visual LISP does not provide any mechanism for importing a function that is defined in the AutoLISP environment.

Exposing Functions

Visual LISP presently offers two procedures for exposing functions: the Command Line designation ("c:") and the vl-acad-defun function.

Note: AutoCAD automatically registers an entry point during the load time for any ObjectARX application. With respect to the AutoLISP environment, to call externally defined functions in AutoLISP, you need to expose the function in the ObjectARX application. It is only in a Visual LISP environment where you will need to manually register the entry point.

Command Line Functions ("c:")

You can expose a function by designating it as a Command Line function (the function name is preceded by a "c:"). This designation is considered an Implicit Export operation. For example, the following function, which may exist in an ObjectARX application, would be exposed:

(defun c:foo ()
(princ "Hi!")
)

However, the following function would remain unexposed unless you use the vl-acad-defun function explained later:

(defun foo ()
(princ "Hi!")
)

Note: You can block the Implicit Export feature by setting the *C-COLON-EXPORT* variable to nil in the Visual LISP environment. Any Command Line functions that are exposed in a Visual LISP environment after setting *C-COLON-EXPORT* to nil will not be available in AutoCAD or AutoLISP.

The vl-acad-defun Function

Complementary to the Command Line procedure, use of the vl-acad-defun function is considered an Explicit Export operation. This function requires a single argument as a quoted list: the name of the defined function. Consider the following code:

(defun c:foo ()
(vl-acad-defun ?foo2)
)

(defun foo2 ()
(expr?)
(expr?)
)

As you can see, the foo2 function remains unexposed until you make a call to the c:foo function. This procedure offers the user the most control over when a function actually becomes available. While you can place the vl-acad-defun expression outside of a defined function and evaluate it during load, you can also include it within a defined function and therefore have complete control over the exposure process time (see step 7 of the Application wizard in Chapter 7 of Help).

It is important to note that vl-acad-defun only exposes functions in a compiled Visual LISP ObjectARX application if you select Initialize in load time in step 7 of the Application wizard when compiling your Visual LISP source code. Otherwise, it is currently possible to expose functions with the default option of Form the list automatically in step 7 by using the following syntax with your function name:

(pragma ((export-to-ACAD foo2)))

The same temporary syntax will also have to be used for any of your own initialization functions you include and run during the RTS initialization which you might package with your compiled code.

Registering Application Entry Points

Remembering that you do not need to register entry points for ObjectARX applications with respect to the AutoLISP environment, there are two procedures for registering entry points in a Visual LISP environment. The first is by using the vlisp-import-exsubrs function and the second is through the use of an XDF file.

The vlisp-import-exsubrs Function

Compared to XDF files, the vlisp-import-exsubrs function offers more control to the user in registering application entry points. Consider the following code:

(defun c:foo ()
(vlisp-import-exsubrs ?("myapp" "foo2"))
(foo2)
)

The result is that even if no XDF file is available, c:foo will still be able to successfully call foo2, provided that the associated application is currently loaded. The syntax for this function is as follows:

(vlisp-import-exsubrs '("[appname]" "[function name]" "[function name]" etc?))

It returns the name of the application and the function names contained in the expression including any function names that were already recognized in that application.

Tip: Although it is recognized in the Visual LISP documentation, the hard coded path for the appname argument is not required.

You can test whether a function is defined in your environment or another environment using the type function. For example, at the Visual LISP Console prompt, (type setq) will return SUBR indicating that the setq function is built into Visual LISP. Here are the possible returns from passing a function name to the type function within Visual LISP:

SUBR. Indicates that the function is built into the environment.

USUBR. Indicates a user defined function that was added to the environment. In AutoLISP, LIST would be returned because user defined functions in AutoLISP are not compiled, they are lists. However, in Visual LISP, user defined functions exist as compiled routines instead of lists as soon as you load them from the Text Editor to the Visual LISP IDE.

EXSUBR. Indicates a function that is defined in an external ADS application.

EXRXSUBR. Indicates a function that is defined in an external ARX application.

Note: In the case of externally defined functions, you can reference functions in other ObjectARX applications in addition to the ObjectARX applications you develop with Visual LISP using vlisp-import-exsubrs or XDF files.

Externally Defined Function Files (XDF)

Externally Defined Function files (XDF) offer a simple solution for creating application entry points and recognizing properly exposed functions. Once created, they can be packaged into any new ObjectARX application which needs to call those external functions in step 6 of the Application wizard.

An XDF file is similar to the vlisp-import-exsubrs function in that its core elements comprise the application's name and a list of its exposed functions. However, applications that make calls to functions listed in an XDF file require no preparatory code; you simply need to load the necessary ObjectARX applications into the environment.

You can write XDF files in an ASCII text editor, however, Visual LISP offers a file called Make-XDF.lsplocated in the root directory of your Visual LISP installation. By loading this from within AutoCAD and selecting your ARX file, it creates a corresponding XDF file.

XDF files are only evaluated when you start Visual LISP with ObjectARX modules preloaded in AutoCAD, or when you load your ObjectARX from within Visual LISP. Visual LISP provides no command to force it to evaluate an XDF file. For this reason, you must follow specific rules to make sure your XDF files are recognized and evaluated:

  • The XDF file must have the same name as the ARX file with which it is associated. For example: Myfun.ARX and Myfun.XDF.
  • You must store the XDF file in one of the following locations depending on the scenario: If you are calling an externally defined function from within Visual LISP compiled ObjectARX, include the appropriate XDF file in step 6 of the Application wizard.

Note: It is important to understand that even if the XDF file is included, you must still load its associated ObjectARX module to make the functions available.

If you are calling an externally defined function from within Visual LISP itself, you must either include the XDF file in the same location as the ARX file with which it is associated or in the Visual LISP root directory where the Visual LISP RTS is located. For more information about the use of the Make-XDF.lsp utility, as well as the syntax for XDF files, please see the following topic in Visual LISP Help:

Chapter 7 -- Building Applications
Building Stand-alone Applications
Making Functions Known to AutoCAD
Identifying Functions Defined in External Applications

Externally Defined ADS Functions

It was stated earlier in the solution that you can call externally defined functions from other ObjectARX applications in addition to the ObjectARX applications you develop with Visual LISP. There is also Visual LISP documentation that suggests you can call externally defined functions in ADS applications.

Even though it is possible to create XDF files for them with the Make-XDF.Lsp utility, it is presently not possible to call or recognize those ADS functions in Visual LISP. Your ADS applications will have to be recompiled as ADSRX applications for the Visual LISP environment to access those externally defined functions with either of the two previously described methods for creating application entry points.


Give us your feedback on this document:
 Resolved my issue.
 Helpful but incomplete.
 Difficult to find.
 Difficult to understand.
 Did not resolve my issue.
 Document contains broken links and references.
 No comment.
 

AUTODESK DOES NOT GUARANTEE THAT YOU WILL BE ABLE TO SUCCESSFULLY DOWNLOAD OR IMPLEMENT ANY SERVICE PACK OR WORKAROUND, OR ANY OF THE TIPS, TRICKS, EXAMPLES OR SUGGESTIONS OUTLINED IN ANY AUTODESK PRODUCT SUPPORT TECHNICAL DOCUMENTS. TECHNICAL DOCUMENTS, SERVICE PACKS AND WORKAROUNDS ARE SUBJECT TO CHANGE WITHOUT NOTICE TO YOU. AUTODESK PROVIDES TECHNICAL DOCUMENTS, SERVICE PACKS AND WORKAROUNDS "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL AUTODESK OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF DATA, OR LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, THAT MAY OCCUR AS A RESULT OF IMPLEMENTING ANY SERVICE PACK OR WORKAROUND, OR ANY SUGGESTION OUTLINED IN ANY AUTODESK PRODUCT SUPPORT TECHNICAL DOCUMENT, EVEN IF AUTODESK OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.