5.11.1 COM Automation
The ffi/com library is based on the MysterX library by Paul Steckler. MysterX is included with Racket but deprecated, and it will be replaced in the next version with a partial compability library that redirects to this one.
5.11.1.1 GUIDs, CLSIDs, IIDs, and ProgIDs
A GUID corresponds an a _GUID structure at the unsafe layer.
procedure
(string->guid str) → guid?
str : string?
procedure
(string->clsid str) → clsid?
str : string?
procedure
(string->iid str) → iid?
str : string?
The string->clsid and string->iid functions are the same as string->guid.
procedure
(guid->string g) → string?
g : guid?
procedure
(progid->clsid progid) → clsid?
progid : string?
procedure
(clsid->progid clsid) → (or/c string? #f)
clsid : clsid?
The progid->clsid function accepts a versionless ProgID, in which case it produces the CLSID of the most recent available version. The clsid->progid function always produces a ProgID with its version.
5.11.1.2 COM Objects
procedure
(com-object? obj) → boolean?
obj : com-object?
procedure
(com-create-instance clsid-or-progid [where]) → com-object?
clsid-or-progid : (or/c clsid? string?) where : (or/c (one-of/c 'local 'remote) string?) = 'local
The optional where argument indicates a location for running the instance, and may be 'local, 'remote, or a string indicating a machine name. See Remote COM servers (DCOM) for more information.
An object can be created this way for any COM class, but functions such as com-invoke work only if the object supports the IDispatch COM automation interface.
The resulting object is registered with the current custodian, which retains a reference to the object until it is released with com-release or the custodian is shut down.
procedure
(com-release obj) → void?
obj : com-object?
If obj has already been released, com-release has no effect.
procedure
(com-get-active-object clsid-or-progid) → com-object?
clsid-or-progid : (or/c clsid? string?)
procedure
(com-object-clsid obj) → clsid?
obj : com-object?
procedure
(com-object-set-clsid! obj clsid) → void?
obj : com-object? clsid : clsid?
procedure
(com-object-eq? obj1 obj2) → boolean?
obj1 : com-object? obj2 : com-object?
If two references to a COM object are the same according to com-object-eq?, then they are also the same according to equal?. Two com-object-eq? references are not necessarily eq?, however.
procedure
(com-object-type obj) → com-type?
obj : com-object?
procedure
(com-type=? t1 t2) → boolean?
t1 : com-type? t2 : com-type?
5.11.1.3 COM Methods
procedure
(com-methods obj/type) → (listof string?)
obj/type : (or/c com-object? com-type?)
procedure
(com-method-type obj/type method-name)
→
(list/c '-> (listof type-description?) type-description?) obj/type : (or/c com-object? com-type?) method-name : string?
procedure
(com-invoke obj method-name v ...) → any/c
obj : com-object? method-name : string? v : any/c
The types of arguments are determined via com-method-type, if possible, and type-describe wrappers in the vs are simply replaced with the values that they wrap. If the types are not available from com-method-type, then types are inferred for each v with attention to descriptions in any type-describe wrappers in v.
5.11.1.4 COM Properties
procedure
(com-get-properties obj/type) → (listof string?)
obj/type : (or/c com-object? com-type?)
procedure
(com-get-property-type obj/type property-name) → (list/c '-> '() type-description?) obj/type : (or/c com-object? com-type?) property-name : string?
procedure
(com-get-property obj property ...+) → any/c
obj : com-object?
property :
(or/c string? (cons/c string? list?))
Each property is either a property-name string or a list that starts with a property-name string and continues with arguments for a parameterized property.
procedure
(com-get-property* obj property v ...) → any/c
obj : com-object? property : string? v : any/c
procedure
(com-set-properties obj/type) → (listof string?)
obj/type : (or/c com-object? com-type?)
procedure
(com-set-property-type obj/type property-name) → (list/c '-> (list/c type-description?) 'void) obj/type : (or/c com-object? com-type?) property-name : string?
procedure
(com-set-property! obj property ...+ v) → void?
obj : com-object?
property :
(or/c string? (cons/c string? list?)) v : any/c
The type of the property is determined via com-property-type, if possible, and type-describe wrappers in v are then replaced with the values that they wrap. If the type is not available from com-property-type, then a type is inferred for v with attention to the descriptions in any type-describe wrappers in v.
5.11.1.5 COM Events
procedure
(com-events obj/type) → (listof string?)
obj/type : (or/c com-object? com-type?)
procedure
(com-event-type obj/type event-name)
→ (list/c '-> (listof type-description?) 'void) obj/type : (or/c com-object? com-type?) event-name : string?
procedure
(com-event-executor? v) → boolean?
v : any/c
procedure
procedure
(com-register-event-callback obj name proc com-ev-ex) → void? obj : com-object? name : string? proc : procedure? com-ev-ex : com-event-executor?
Only one callback can be registered for each obj and name combination.
Registration of event callbacks relies on prior registration of the COM class implemented by "myssink.dll" as distributed with Racket. (The DLL is the same for all Racket versions.)
procedure
(com-unregister-event-callback obj name) → void?
obj : com-object? name : string?
5.11.1.6 Interface Pointers
procedure
(com-object-get-iunknown obj) → com-iunkown?
obj : com-object?
procedure
obj : com-object?
procedure
(com-iunknown? v) → boolean?
v : any/c
procedure
(com-idispatch? v) → boolean?
v : any/c
5.11.1.7 Remote COM servers (DCOM)
The optional where argument to com-create-instance can be 'remote. In that case, the server instance is run at the location given by the Registry key
HKEY_CLASSES_ROOT\AppID\‹CLSID›\RemoteServerName
where ‹CLSID› is the CLSID of the application. This key may be set using the dcomcnfg utility. From dcomcnfg, pick the application to be run on the Applications tab, then click on the Properties button. On the Location tab, choose Run application on the following computer, and enter the machine name.
To run a COM remote server, the registry on the client machine must contain an entry at
HKEY_CLASSES_ROOT\CLSID\‹CLSID›
where ‹CLSID› is the CLSID for the server. The server application itself need not be installed on the client machine.
There are a number of configuration issues relating to DCOM. See
for more information on how to setup client and server machines for DCOM.
5.11.1.8 COM Types
In the result of a function like com-method-type, symbols are used to represent various atomic types:
'int —
a 32-bit signed integer 'unsigned-int —
a 32-bit unsigned integer 'short-int —
a 16-bit signed integer 'unsigned-short —
a 16-bit unsigned integer 'signed-char —
an 8-bit signed integer 'char —
an 8-bit unsigned integer 'long-long —
a 64-bit signed integer 'unsigned-long-long —
a 64-bit unsigned integer 'float —
a 32-bit floating-point number 'double —
a 64-bit floating-point number 'currency —
an exact number that, when multiplied by 10,000, is a 64-bit signed integer 'boolean —
a boolean 'string —
a string 'com-object —
a COM object as in com-object? 'iunknown —
like 'com-object, but also accepts an IUnknown pointer as in com-iunknown? 'com-enumeration —
a 32-bit signed integer 'any —
any of the above, or an array when not nested in an array type '... —
treated like 'any, but when it appears at the end of the sequence of types for arguments, allows the preceding type 0 or more times 'void —
no value
A type symbol wrapped in a list with 'box, such as '(box int), is a call-by-reference argument. A box supplied for the argument is updated with a new value when the method returns.
A type wrapped in a list with 'opt, such as '(opt (box int)), is an optional argument. The argument can be omitted or replaced with com-omit.
A type wrapped in a list with 'array and a positive exact integer, such as '(array 7 int), represents a vector of values to be used as a COM array. A '? can be used in place of the length integer to support a vector of any length. Array types with non-'? lengths can be nested to specify a multidimensional array as represented by nested vectors.
A type wrapped in a list with 'variant, such as '(variant (array 7 int)), is the same as the wrapped type, but a 'variant wrapper within an 'array type prevents construction of another array dimension. For example, '(array 2 (array 3 int)) is a two-dimensional array of integers, but '(array 2 (variant (array 3 int))) is a one-dimensional array whose elements are one-dimensional arrays of integers.
When type information is not available, functions like com-invoke infer type descriptions from arguments. Inference chooses 'boolean for booleans; the first of 'int, 'unsigned-int, 'long-long, 'unsigned-long-long that fits for an exact integer; 'double for inexact real numbers; 'string for a string; 'com-object and 'iunknown for corresponding COM object references; and an 'array type for a vector, where the element type is inferred from vector values, resorting to 'any if any two elements have different inferred types.
procedure
(type-description? v) → boolean?
v : any/c
procedure
(type-described? v) → boolean?
v : any/c
procedure
(type-describe v desc) → type-described?
v : any/c desc : type-description?
procedure
(type-described-value td) → any/c
td : type-described?
procedure
td : type-described?
A type-describe wrapper combines a base value with a type description. The description is used instead of an automatically inferred COM argument type when no type is available for from COM automation a method for com-invoke or a property for com-set-property!. A wrapper can be placed on an immediate value, or it can be on a value within a box or vector.
5.11.1.9 Class Display Names
A coclass name corresponds to the display name of a COM class; the display name is not uniquely mapped to a COM class, and some COM classes have no display name.
procedure
(com-all-coclasses) → (listof string?)
procedure
(com-all-controls) → (listof string?)
procedure
(coclass->clsid coclass) → clsid?
coclass : string?
procedure
(clsid->coclass clsid) → string?
clsid : clsid?