Creo Elements/Direct Modeling COM & .NET API

Creo Elements/Direct Modeling COM & .NET API - Lisp interoperability


Introduction

Using the APIs described below, Creo Elements/Direct Modeling extensions written in Lisp can communicate with COM/.NET add-ins or with generic COM/.NET components. Developers can use this to drive COM or .NET components from Lisp and extend Creo Elements/Direct Modeling's built-in functionality.

All Lisp interoperability APIs are in the Lisp package .net. To call such an API, either the package has to specified explicitly, or its symbols must be made available via use-package:

    ;; Alternative 1: Prefix the API call with the package name
    (.net:get-property app "Version")
		
    ;; Alternative 2: use-package
    (in-package :myextension)
    (use-package :.net)
    ...
    (get-property app "Version")

The available APIs will work with all COM/.NET components which are scriptable, i.e. those which provide an automation (IDispatch) interface. When working with automation objects, the Lisp interoperability layer and the Lisp garbage collector automatically take care of COM-style reference counting. Automation objects which have been instantiated through Lisp, but are no longer used from Lisp code, are released automatically the next time the Lisp garbage collector runs.

Caveat: References to automation objects in global Lisp variables will keep the automation object alive for as long as the client (in this case: Creo Elements/Direct Modeling) runs!

Functionality in pure .NET components can be called from Lisp by first registering the .NET component as a COM component (using the regasm tool) and then using the .NET component through its COM wrapper.


Error handling

For most of the APIs presented below, the interoperability layer will (by default) handle COM or .NET errors by reporting a run-time error to the user, i.e. a message box with error details will be displayed.

Run-time error signalling can be suppressed by setting the variable .net:*report-errors* to a value of nil. In this case, errors will be reported via the function's return value, i.e. the caller must take care to check the return values and act accordingly.


Automation object instantiation

.net:create-object

Instantiates an arbitrary automation object.

    (.net:create-object serverspec)

Description

If the specified automation server is not running yet, it will be loaded in the background. Otherwise, a reference to an already running server instance is returned.

Parameters

serverspec {STRING}
Specifies the automation object server which is to be instantiated. This is a string parameter which contains either a ProgID or a CLSID (GUID).

Return value

nil
Instantiation failed, no connection to the server could be made
Object reference {LCOMINTERFACE}
If instantiation succeeds, a reference to the server object's default dispatch interface is returned.

Examples

    (setq app (.net:create-object "CoCreate.OsdmServer"))	
    (setq excel (.net:create-object "Excel.Application"))
    (setq FileSystemObject (.net:create-object "0D43FE01-F093-11CF-8940-00A0C9054228"))

See also

osdm-application, get-active-object, get-object

.net:osdm-application

Connect to the IApplication interface of the Creo Elements/Direct Modeling object model.

    (.net:osdm-application)

Description

Using the .net:osdm-application API is the recommended way to retrieve a reference to the IApplication interface of the Creo Elements/Direct Modeling object model.

Return value

nil
Connection failed, object model could not be initialized.
Object reference {LCOMINTERFACE}
Object reference to Creo Elements/Direct Modeling's IApplication interface.

Examples

    (setq app (.net:osdm-application))

See also

create-object

.net:get-active-object

Retrieves a reference to an already running automation object server.

    (.net:get-active-object serverspec)

Description

Retrieves a reference to an already running instance of the specified automation object server. If the automation object server is not running, no attempts will be made to load or start it.

Parameters

serverspec {STRING}
Specifies the automation object server which is to be instantiated. This is a string parameter which contains either a ProgID or a CLSID (GUID).

Return value

nil
No connection to the server could be made
Object reference {LCOMINTERFACE}
Server is already running, and a connection could be made; a reference to the server object's default dispatch interface is returned.

Examples

    (setq excel (.net:get-active-object "Excel.Application"))

See also

create-object, get-object

.net:get-object

Retrieves a reference to an automation object through a moniker.

    (.net:get-object moniker)

Description

Retrieves a reference to an automation object which is described by a moniker - in most cases, a filename.

Parameters

moniker {STRING}
Display name, in string format, of the object to be created.

Return value

nil
No connection to the server could be made
Object reference {LCOMINTERFACE}
A connection could be established; a reference to the server object's default dispatch interface is returned.

Examples

    (setq excel (.net:get-object "c:\\temp\\spreadsheet.xls"))

See also

create-object, get-active-object

Automation calls

When calling functions in interfaces implemented by automation servers, Lisp objects can be passed as parameters. Those objects are converted into automation-compatible types (variants) in the Lisp interoperability layer. On the way back, values returned from the automation functions are converted into Lisp objects.

Sometimes, there is no direct 1:1 relationship between Lisp datatypes and automation datatypes. For example, there is no equivalent of a Lisp list in an automation server. Also, the Lisp interoperability layer does not try to exhaustively map all conceivable types, but only a subset which covers the vast majority of all practical cases.

Conversion of Lisp objects into automation datatypes

When calling COM/.NET functionality from Lisp, the interoperability layer converts Lisp types into automation-compatible types (variants) according to the following table:

Lisp type Automation type
Keyword :empty VT_EMPTY
Keyword :null VT_NULL
string VT_BSTR
fixnum VT_I4
short-float VT_R4
long-float, ratio VT_R8
character VT_UI2
list, vector VT_VECTOR|VT_VARIANT
LCOMINTERFACE VT_DISPATCH
.NET:NOTHING VT_DISPATCH with a null pointer
t/nil VT_BOOL
symbol Reference parameter
SEL_ITEM structure ((:selection-item sel_item)) * VT_DISPATCH carrying an ISelectionItem interface pointer
list of SEL_ITEMs ((:selection-item sel_item))* VT_ARRAY of VT_DISPATCH elements, each carrying an ISelectionItem interface pointer
other Lisp structures marshalling not supported.

Automation functions can have multiple "out" (return) parameters. For example, there could be a function which returns three double values specifying the X, Y and Z component of a vector:

    HRESULT GetVector([out]double *x, [out]double *y, [out]double *y);  /* IDL notation */

Such a function can be called from Lisp like this:

    (let ((x 0.0) (y 0.0) (z 0.0))
      (.net:invoke obj "GetVector" 'x 'y 'z))

Specifying a symbol as a parameter signals to the Lisp interoperability layer that a reference to a variable should be passed, rather than the variable itself. The called function can use those references to return multiple values.

*)In the Lisp-based Developer's Kit (also known as "Integration Kit"), objects in Creo Elements/Direct Modeling (be they structural, topological or geometrical) are usually referred to through a Lisp structure called SEL_ITEM. This structure serves as a handle to an object and is returned by Integration Kit functions when a reference to an object is requested, for example as the result of a selection in a dialog.

The .NET/COM API provides the SelectionItem object and the associated ISelectionItem interface as the equivalent of the SEL_ITEM structure in the Lisp world. Because of the special role of SEL_ITEM structures in the Integration Kit, the Lisp interoperability layer provides a shortcut notation which directly converts Lisp's SEL_ITEM structure into SelectionItem objects.

    (.net:invoke obj "SomeFunction" (:selection-item sel_item))

Conversion of automation datatypes into Lisp objects

When returning automation-compatible types from COM/.NET functionality to Lisp, the interoperability layer converts them into Lisp types according to the following table:

Automation type Lisp type
VT_EMPTY Keyword :empty
VT_NULL Keyword :null
VT_U1, VT_I1, VT_UI2, VT_I2 character
VT_I4, VT_UI4, VT_INT, VT_UINT fixnum
VT_ERROR fixnum
VT_BSTR string
VT_R4 short-float
VT_R8 long-float
VT_BOOL t/nil
VT_DISPATCH, VT_UNKNOWN 1 2 LCOMINTERFACE, SEL_ITEM or nil
VT_DATE, VT_CY string
VT_VECTOR, 1-dimensional VT_ARRAY vector

1)When calling .NET APIs that return selection item objects via invoke, invoke-addin or get-property, those objects are returned either as a LCOMINTERFACE, or can be requested to be converted into SEL_ITEM structures. Conversion to SEL_ITEM requires to pass the :raw-return-values nil key-value pair as first parameter to the function call.

2)A VT_DISPATCH or VT_UNKNOWN pointer that is null will be converted into nil. Note that this conversion is not symmetric, i.e. nil will convert to a VT_BOOL. In order to pass a null pointer to a COM function, use the .NET:nothing constant.

.net:invoke

Invokes a function in an interface implemented by an automation server.

     (.net:invoke objectref function &optional :raw-return-values t/nil args...)

Description

Converts all args into automation-compatible data types according to the table above, then calls function in the automation object specified by objectref.

Parameters

objectref {LCOMINTERFACE}
Reference to an automation object which was previously acquired by calling an instantiation function such as create-object, or by calling a function in an automation object which returns an object reference.
function {STRING, KEYWORD, SYMBOL or FIXNUM}
Specifies the function to be called. Keywords and symbols are translated into their string representation. Values of type FIXNUM are assumed to represent dispatch IDs and are passed directly to the COM automation object.
:raw-return-values {t / nil}
This key-value pair is optional. The default is 't'. Effects the way in that the return value(s) are marshalled. See marshalling of returned SelectionItems for details.
args
Any number of Lisp objects to be passed to the called function. Each argument is transformed as described in Conversion of Lisp objects into automation datatypes.

Return value

If the called function has only one return value, it is returned as the result of the invoke call.

The caller can pass variables by reference rather by value, which allows automation functions to have multiple return values. To indicate by-reference semantics, use the following pattern:

    (setf foo 42)  ;; establish integer variable
    (invoke obj "Foobar" 'foo)  ;; foo passed by reference

All return values from automation functions are converted according to Conversion of automation datatypes into Lisp objects.

By default, if an error occurs while calling the specified function, a Lisp run-time error will be reported. If .net:*report-errors* has been set to nil, invoke returns nil when an error occurs.

Example

  (let ((app (.net:osdm-application)))
    (.net:invoke app :LockUserInterface)
    (.net:invoke app "ILoadFile" "c:/temp/foo.pkg")
    (.net:invoke app 'UnlockUserInterface))

.net:get-property

Gets the value of an automation object property.

    (.net:get-property objectref property &optional :raw-return-values t/nil &optional args)

Description

This function inquires the value of an automation object property.

Parameters

objectref {LCOMINTERFACE}
Reference to an automation object which was previously acquired by calling an instantiation function such as create-object, or by calling a function in an automation object which returns an object reference.
property (STRING, KEYWORD, SYMBOL or FIXNUM}
Specifies the name of the property to be inquired. Keywords and symbols are translated into their string representation. Values of type FIXNUM are assumed to represent dispatch IDs and are passed directly to the COM automation object.
:raw-return-values {t / nil}
This key-value pair is optional. The default is 't'. Effects the way in that the return value(s) are marshalled. See marshalling of returned SelectionItems for details.
args
An arbitrary number of Lisp objects to be passed to the automation object's property inquiry function as arguments. The Lisp objects are converted according to Conversion of automation datatypes into Lisp objects. In most cases, no arguments must be passed to inquire a property.

Return value

The value of the inquired property is returned as the result of the get-property call. It is converted according to the rules detailled in Conversion of automation datatypes into Lisp objects.

By default, if a communication error occurs while retrieving the specified property, a Lisp run-time error will be reported. If .net:*report-errors* has been set to nil, get-property returns nil when an error occurs.

Example

    (print (.net:get-property (.net:osdm-application) "Version"))

.net:set-property, .net:set-property-ref

Sets a property of an automation object.

    (.net:set-property objectref property newval)
    (.net:set-property-ref objectref property newval)

Description

This function sets the value of an automation object property.

Parameters

objectref {LCOMINTERFACE}
Reference to an automation object which was previously acquired by calling an instantiation function such as create-object, or by calling a function in an automation object which returns an object reference.
property (STRING, KEYWORD, SYMBOL or FIXNUM}
Specifies the name of the property to be modified. Keywords and symbols are translated into their string representation. Values of type FIXNUM are assumed to represent dispatch IDs and are passed directly to the COM automation object.
newval
An arbitrary number of Lisp objects to be passed to the automation object's property setter function as arguments. The Lisp objects are converted according to Conversion of automation datatypes into Lisp objects. In most cases, only one argument must be passed to set a property. For set-property-ref, newval must refer to an object, and the property must accept an object reference.

Return value

The property setter may return a value which is converted according to the rules detailled in Conversion of automation datatypes into Lisp objects.

By default, if a communication error occurs while setting the specified property, a Lisp run-time error will be reported. If .net:*report-errors* has been set to nil, set-property returns nil when an error occurs.

Example

    (.net:set-property (create-object "Excel.Application") "Visible" t)

.net:foreach

Iterates over a collection of items and executes a function for each item.

    (foreach collection function)

Description

foreach iterates over all items in a collection of objects. For each item in the collection, it will call function, which receives the item as an input parameter.

Parameters

collection {LCOMINTERFACE}
Any collection of items provided by an automation object.
function {FUNCTION}
A Lisp object which specifies a function which is called for each item in the collection. This can be a reference to a function called elsewhere or an "inline" lambda form.

Return value

nil
Could not iterate the collection.
t
Successfully iterated over the collection.

Examples

  ;; Example: Using foreach with an "inline" lambda form
  (let* ((fs (create-object "Scripting.FileSystemObject"))))
         (foreach (get-property fs "Drives") 
            #'(lambda(item) (format t " ~A" (get-property item "DriveLetter"))))
  ;; Example: Nested foreach, once with reference to 
  ;;          separate function, once using a lambda expression
  (defun per-workbook(item)
    (foreach (get-property item "Worksheets")
       #'(lambda(sheet) (invoke sheet "Close"))))
			
  (defun close-all-sheets()
    (let* ((excel (create-object "Excel.Application")))			 
         (foreach (get-property excel "Workbooks") 'per-workbook)))

.net:selection-item

Converts a Lisp SEL_ITEM structure into an object of type ISelectionItem.

      (.net:selection-item sel_item)

Description

Integration Kit functionality identifies objects using SEL_ITEM structures. The .NET API has an equivalent object type which provides an ISelectionItem interface. This function converts a Lisp SEL_ITEM object into an object of type ISelectionItem.

Parameters

sel_item {SEL_ITEM}
A Lisp structure of type SEL_ITEM.

Return value

nil
Could not convert the SEL_ITEM structure.
objectref {LCOMINTERFACE}
Reference to an object of type ISelectionItem

Example

      (setf entity (.net:invoke (.net:selection-item sel-item) "IReferencedEntity"))

.net:query-interface

Queries an Automation object for a given interface.

      (.net:query-interface objectref interfaceid)

Description

Use query-interface to check if a given Automation object implements an interface.

Parameters

objectref {LCOMINTERFACE}
Reference to an automation object which was previously acquired by calling an instantiation function such as create-object, or by calling a function in an automation object which returns an object reference.
interfaceid {STRING}
An interface ID, i.e. a globally unique ID (GUID) which identifies an automation-compatible interface.

Return value

nil
Requested interface not available on this object.
objectref {LCOMINTERFACE}
Reference to the requested interface.

Example

  (setf face (.net:query-interface entity "594C09BB-6427-472C-83CE-DE14EA5E5000"))
  ;; Check if an entity is a face. 594C09BB-6427-472C-83CE-DE14EA5E5000 is the IID for 
  ;; CoCreate.Osdm.IFace.

.net:connect-object

Connects an automation object to a Lisp event handler.

      (.net:connect-object objectref eventhandler)

Description

Use connect-object to receive event notifications from Automation objects.

Parameters

objectref {LCOMINTERFACE}
Reference to an automation object which was previously acquired by calling an instantiation function such as create-object, or by calling a function in an automation object which returns an object reference.
eventhandler {FUNCTION}
A Lisp function specifier.

Return value

nil
Could not connect to object.
objectref {LCOMINTERFACE}
Handle to an event sink object; this handle is needed later to disconnect from the Automation object using disconnect-object.

Example

  (defun my-event-handler(event-id event-args)
    (format t "Event ID = ~A, event arguments = ~A~%" event-id event-args))

  (setf event-sink (.net:connect-object some-object 'my-event-handler))

.net:disconnect-object

Disconnect an automation object from a Lisp event handler.

      (.net:disconnect-object objectref)

Description

Use disconnect-object if you no longer want to receive event notifications from an Automation object.

Parameters

objectref {LCOMINTERFACE}
Reference to an event sink object as returned by connect-object.

Return value

nil
Could not disconnect from object.
t
Event connection has now been terminated.

Example

  (defun my-event-handler(event-id event-args)
    (format t "Event ID = ~A, event arguments = ~A~%" event-id event-args))

  (setf event-sink (.net:connect-object some-object 'my-event-handler))
	...
	(.net:disconnect-object event-sink)

.net:nothing

Constant which represents an IDispatch pointer that is null.

      .net:nothing

Description

Sometimes the need arises to pass a null pointer to a COM function. nil would be an intuitive way to do this, but this is a boolean value which is converted into a VT_BOOL. Instead, the .net:nothing constant must be used.

Example

  ;; get all side faces of a sheet-metal part, providing neither a neighbour face
  ;; nor a bounding box as filter.
  (setf faces (.net:invoke sheet-part "InqISideFaces" .net:nothing .net:nothing))

Add-in support

.net:acquire-addin

Activates a COM/.NET addin.

     (.net:acquire-addin progid)

Description

Loads and activates COM/.NET add-in modules which were previously installed for OSDM. If the add-in is already active, that instance is shared. For details on how to create and deploy add-ins, please consult the documentation on API client types.

Parameters

progid {STRING}
COM ProgID identifying the add-in

Return value

nil
Add-in could not be loaded or activated.
Add-in reference {LCOMINTERFACE}
Reference to the add-in's default dispatch interface

Example

    (.net:acquire-addin "CoCreate.TestAddin")

See also

invoke-addin, release-addin

.net:invoke-addin

Invokes functionality defined in an add-in.

    (invoke-addin progid function params...)

Description

Calls a function defined in a COM/.NET add-in. For details on how to build such a function, consult the documentation on Integrating Lisp and Add-ins.

Parameters

progid {STRING}
COM ProgID identifying the add-in
function {STRING}
Name of the function to be called in the add-in.
params... {COM/.NET-compatible data types}
Any number of parameters to be passed to the function in the add-in.

The Lisp interoperability layer converts Lisp values into automation-compatible data types (so-called variants) according to this table.

Return value

retval {any automation-compatible Lisp type}
Values returned by the function called in the add-in.

The interoperability layer converts automation-compatible return values into Lisp types according to this table.

By default, if an error occurs while calling the specified addin function, a Lisp run-time error will be reported. If .net:*report-errors* has been set to nil, invoke-addin returns nil when an error occurs.

Example

    (setf retval (.net:invoke-addin "CoCreate.TestAddin" "ExportXML"
                                   (list (sd-pathname-to-obj "/p1"))))
    ;; now process return value in retval

See also

acquire-addin, release-addin, invoke

.net:release-addin

    (.net:release-addin progid)

Description

Releases a connection to the specified add-in. If no other connections are open, the add-in is deactivated and unloaded. For details on how to create and deploy add-ins, please consult the documentation on API client types.

Parameters

progid {STRING}
COM ProgID identifying the add-in

Return value

nil
Could not release the connection to the add-in.
t
Add-in connection was released.

Example

   (.net:release-addin "CoCreate.TestAddin")

See also

acquire-addin, invoke-addin