5.9.2 COM Classes and Interfaces
The
ffi/unsafe/com library
exports all of
ffi/com, and it also supports direct,
FFI-based calls to COM object methods.
5.9.2.1 Describing COM Interfaces
|
|
maybe-alloc-spec | | = | | | | | | | | #:release-with-function function-id | | | | | | #:release-with-method method-id | | | | | | #:releases |
|
Defines
_id as an interface that extends
_super-id,
where
_super-id is often
_IUnknown, and that
includes methods named by
method-id. The
_id and
_super-id identifiers must start with an underscore. A
_super-id _vt must also be defined
for deriving a virtual-method table type.
The order of the method-ids must match the specification of
the COM interface, not including methods inherited from
_super-id. Each method type produced by ctype-expr
that is not _fpointer must be a function type whose first
argument is the “self” pointer, usually constructed with
_mfun or _hmfun.
The define-com-interface form binds _id,
id ?, _id -pointer,
_id _ vt (for the virtual-method
table), _id _ vt-pointer, and
method-id for each method whose ctype-expr is not
_fpointer. (In other words, use _fpointer as a
placeholder for methods of the interface that you do not need to
call.) An instance of the interface will have type
_id -pointer. Each defined method-id is
bound to a function-like macro that expects a
_id -pointer as its first argument and the method
arguments as the remaining arguments.
A maybe-alloc-spec describes allocation and finalization
information for a method along the lines of
ffi/unsafe/alloc. If the maybe-alloc-spec is
#:release-with-function function-id, then
function-id is used to deallocate the result produced by the
method, unless the result is explictly deallocated before it becomes
unreachable; for exmaple, #:release-with-function Release is
suitable for a method that returns a COM interface reference that must
be eventually released. The #:release-with-method method-id
form is similar, except that the deallocator is a method on the same
object as the allocating method (i.e., one of the other
method-ids or an inherited method). A #:releases
annotation indicates that a method is a deallocator (so that a value
should not be automatically deallocated if it is explicitly
deallocated using the method).
See COM Interface Example for an example using
define-com-interface.
5.9.2.2 Obtaining COM Interface References
Attempts to extract a
COM interface pointer for the given
COM object. If the object does not support the requested
interface, the result is
#f, otherwise it is cast to the type
intf-pointer-type.
Specific IIDs and intf-pointer-types go together. For
example, IID_IUnknown goes with _IUnknown-pointer.
For a non-#f result, Release function is the
automatic deallocator for the resulting pointer. The pointer is
register with a deallocator after the cast to
intf-pointer-type, which is why QueryInterface
accepts the intf-pointer-type argument (since a cast
generates a fresh reference).
Increments or decrements the reference count on iunknown,
returning the new reference count and releasing the interface
reference if the count goes to zero.
Converts a
COM object into a object that can be used with the
COM automation functions, such as
com-invoke.
5.9.2.3 COM FFI Helpers
(_wfun fun-option ... maybe-args type-spec ... -> type-spec | maybe-wrapper) |
|
(_mfun fun-option ... maybe-args type-spec ... -> type-spec | maybe-wrapper) |
|
Like
_wfun, but adds a
_pointer type (for the
“self” argument of a method) as the first argument
type-spec.
(_hfun fun-option ... type-spec ... -> id output-expr) |
Like
_wfun, but for a function that returns an
_HRESULT. If the result is not zero, then an error is raised
using
windows-error and using
id as the name of the
failed function. Otherwise,
output-expr (as in a
maybe-racket for
_fun) determines the result.
(_hmfun fun-option ... type-spec ... -> id output-expr) |
Some
C types that commonly appear in COM interface
specifications.
The usual value for a
_LCID argument.
COM interfaces often require or return srings that must be allocated
or freed as system strings.
When receiving a string value, cast it to
_string/utf-16 to extract a copy of the string, and then free
the original pointer with SysFreeString.
Raises an exception. The msg strign provides the base error
message, but hresult and its human-readable interpretation
(if available) are added to the message.
5.9.2.4 COM Interface Example
Here’s an example using the Standard Component Categories Manager to
enumerate installed COM classes that are in the different
systemd-defined categories. The example illustrates instantiating a
COM class by CLSID, describing COM interfaces with
define-com-interface, and using allocation specifications to
ensure that resources are reclaimed even if an error is encountered or
the program is interrupted.