64 lines
2.8 KiB
Racket
64 lines
2.8 KiB
Racket
#lang scribble/doc
|
|
@(require scribble/manual
|
|
"com-common.rkt"
|
|
(for-label racket/base
|
|
ffi/unsafe/com))
|
|
|
|
@title[#:style 'toc #:tag "com"]{COM (Common Object Model)}
|
|
|
|
The @racketmodname[ffi/com] and @racketmodname[ffi/unsafe/com]
|
|
libraries support COM interaction in two layers. The safe upper layer
|
|
provides functions for creating COM objects and dynamically
|
|
constructing method calls based on COM automation (i.e., reflective
|
|
information provided by the object). The unsafe lower layer provides a
|
|
syntactic form and functions for working more directly with COM
|
|
objects and interfaces.
|
|
|
|
A @deftech{COM object} instantiates a particular @deftech{COM
|
|
class}. A @tech{COM class} can be specified in either of two ways:
|
|
|
|
@itemlist[
|
|
|
|
@item{A @deftech{CLSID} (class id), which is represented as a
|
|
@tech{GUID}. A @deftech{GUID} (globally unique identifier) is a
|
|
16-byte structure. GUIDs are typically written in string forms such
|
|
as @racket["{A3B0AF9E-2AB0-11D4-B6D2-0060089002FE}"]. The
|
|
@racket[string->guid] and @racket[guid->string] convert between
|
|
string and @tech{GUID} forms. The @racket[string->clsid] function is
|
|
the same as @racket[string->guid], but its use suggests that the
|
|
resulting @tech{GUID} is to be used as a @tech{CLSID}.}
|
|
|
|
@item{A @deftech{ProgID} is a human-readable name, such as
|
|
@racket["MzCom.MzObj.5.2.0.7"], which includes a version number. The
|
|
version number can be omitted in a @tech{ProgID}, in which case the
|
|
most recent available version is used. The operating system provides
|
|
a mapping between @tech{ProgIDs} and @tech{CLSIDs} that is available
|
|
via @racket[progid->clsid] and @racket[clsid->progid].}
|
|
|
|
]
|
|
|
|
A @tech{COM object} can be instantiated either on the local machine or
|
|
on a remote machine. The latter relies on the operating system's
|
|
@deftech{DCOM} (distributed COM) support.
|
|
|
|
Each @tech{COM object} supports some number of @deftech{COM
|
|
interfaces}. A @tech{COM interface} has a programmatic name, such as
|
|
@cpp{IDispatch}, that corresponds to a C-layer protocol. Each
|
|
interface also has an @deftech{IID} (interface id) that is represented
|
|
as a @tech{GUID} such as
|
|
@racket["{00020400-0000-0000-C000-000000000046}"]. Direct calls to COM
|
|
methods require extracting a suitable interface pointer from an object
|
|
using @racket[QueryInterface] and the desired @tech{IID}; the result
|
|
is effectively cast it to a pointer to a dispatch-table pointer, where
|
|
the dispatch table has a statically known size and foreign-function
|
|
content. The @racket[define-com-interface] form simplifies description
|
|
and use of interface pointers. The COM automation layer uses a fixed
|
|
number of reflection interfaces internally, notably @cpp{IDispatch},
|
|
to call methods by name and with safe argument marshaling.
|
|
|
|
@local-table-of-contents[]
|
|
|
|
@include-section["com-auto.scrbl"]
|
|
@include-section["com-intf.scrbl"]
|
|
@include-section["active-x.scrbl"]
|