overview :: tutorial :: reference :: faq
( Work in progress: COM :: COM sample )
Warning: work in progress
On Windows, the ctypes
distribution contains a simple COM
framework. This document is a short reference to the modules
contained in the ctypes.com
package.
ctypes.com
moduleGUID
Instances of this type represent a global unique identifier
guid
used everywhere by COM. GUID
is a subclass of
ctypes.Structure
.
HRESULT(value)
A function to be used as restype for COM interface methods. It returns the value passed to it, or automatically raises a WindowsError with a description if the integer value represents an error code.
STDMETHOD(restype, name, *argtypes)
This is a helper function to define COM interface methods. It returns nothing interesting, except that the return value are used by the interface metaclass to construct the interface vtable.
restype
is the result type of the COM method, typically
HRESULT
, but you can also use other ctypes types. name
is
the name of the COM method. argtypes
is a sequence of
argument types this method requires, these must be ctypes
types like c_int
, POINTER(GUID)
or whatever.
IUnknown
This is the base class for all COM interfaces. Subclasses
must have a _methods_
attribute, which is a list of all COM
interface methods used in this interface in vtable order. The
_methods_
attribute for derived classes must include the
methods of the base class.
It is not necessary to define the _methods_
attribute in the
class definition statement, it can also be assigned later. But
it must be set the first time the interface class is used.
Subclasses must also have an _iid_
attribute, which must be
a GUID
instance, and which is the global unique identifier
for this interface.
Here a is sample interface definition:
class IPersist(IUnknown): _iid_ = GUID("{0000010C-0000-0000-C000-000000000046}") _methods_ = IUnknown._methods_ + [ STDMETHOD(HRESULT, "GetClassID", POINTER(GUID)) ]
These interface definitions are used to implement COM interfaces, or to use COM interfaces. In client code, if you are using the interface, an instance of the interface class is created and you can call methods on it, in server code the interface class provides information to the metaclass so that the interface vtable can be created.
Note that ctypes.com
contains a tool named readtlb
which
creates Python wrapper modules from type libraries (.tlb
files). In addition to interface subclasses these modules
also contain information about the type library itself, the
coclasses, structure, unions, and enums contained in the type
libraries.
The CreateInstance
function (see below), if successful,
returns a pointer to an interface.
These interface pointers have instance methods dynamically
created by the metaclass for all methods defined in the COM
interface, which directly call the underlying C vtable
method. IUnknown
, for example, has QueryInterface
,
AddRef
, and Release
methods.
Although the COM reference counting is mostly handled
automatically by the framework, and you don't need to call
AddRef
and Release
yourself, it may be useful in debugging
- they return the COM reference count of the interface after
incrementing or decrementing it.
QueryInterface
is useful for client side COM programming, it
requires a pointer to a GUID
instance and a pointer to a
pointer to an interface instance, so a typical call would be:
# assuming iunk is a valid pointer to an IUnknown interface... # create an empty pointer to a dispatch interface instance from ctypes.com.automation import IDispatch idisp = POINTER(IDispatch)() # XXX explain # ask the object for a dispatch interface iunk.QueryInterface(byref(IDispatch._iid_), byref(idisp))
This code will request an IDispatch interface pointer and
store it in idisp
, or raise an exception if the object
doesn't support the IDispatch interface. If the call is
successful, you can for example call the GetTypeInfoCount
method to see if this object exposes type information:
count = c_uint() idisp.GetTypeInfoCount(byref(count)) print count.value
CreateInstance(coclass [,interface [,clsctx]])
Calls the CoCreateInstance
api to create a COM
object, and returns a COM interface pointer.
coclass
must have a _reg_clsid_
attribute which is a
string representation of a guid. If interface
is not
specified, the default COM interface which is the first item
in the _com_interfaces_
attribute of coclass
is
used. clsctx
can be used to specify the context in which the
object is run, if not specified,
CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER
is used.
COMObject
This is an abstract base class used to implement COM objects.
Concrete subclasses must provide a _com_interfaces_
class
attribute, which must be a list containing interfaces this
object implements. The interfaces must be subclasses of
IUnknown
.
The COMObject
class contains the implementation of the
IUnknown
interface, you must implement other interfaces
yourself by providing the interface method in the subclass.
ctypes.com.automation
moduleThis module contains automation interfaces, data types and functions.
ctypes.com.server
moduleThis module contains additional functions and interfaces to implement COM servers.
ctypes.com.register
moduleThis module contains functions to register and unregister COM servers with the Windows registry.
ctypes.com.connectionpoints
moduleThis module contains the connectionpoint interfaces definitions, and support code to receive events from COM objects.
ctypes.com.ole
moduleThis module contains some ole interfaces.
ctypes.com.persist
moduleThis module contains persist interfaces.
ctypes.com.w_getopt
module XXX The code in this module will probably be moved into a
ctypes.com.util
module. It contains a w_getopt
function used
to parse Windows style command lines.