I have made some larger changes in the SVN trunk; maybe a little bit
early since I started it some weeks ago and it is not yet ready.

The trunk version number has been changed to 0.5, but I have also
created a comtypes-0.4 branch where I still make small fixes and also
plan to make further maintainance releases.

So, what's new it 0.5?
----------------------

I have committed a new way to implement COM objects with comtypes.
Unfortunately there are some backwards incompatible changes that I
will describe below.

In 0.5, there are two ways to implement COM methods.

The first way is high-level that should normally be used.  You simply
write a method just as you would do in a normal Python object.  The
method will receive [in] and [in, out] parameters as usual, marshalled
as normal Python objects like (unicode) strings, integers, floats,
lists or tuples.  The method should do its processing, and it should
return nothing (= None), a single Python value, or a tuple containing
multiple Python values, depending on the [out] parameters that the COM
method expects.  Exceptions that occur in the code will automatically
be converted to HRESULT values which are returned via COM to the
caller; in addition exception information will be set that can also be
retrieved by the caller.  COM attributes are implemented by implementing
normal Python attributes, either directly in the class or by implementing
a Python property.

The second possibility is to write a low-level COM method.  This
method will be called with all [in], [in, out] and [out] parameters.
The [in] parameters will already be converted to Python objects (int,
string, and so on), but [in, out] or [out] parameters will be passed
as ctypes or comtypes pointer instances.  The method implementation
must return an integer HRESULT value (or None, which has the same
meaning as S_OK), the [in, out] parameters must be retrieved from the
pointer and the return values must be set into the pointer object to
be returned to the caller.  COM attributes are implemented by writing
both a setter and a getter method, named get_<name> and set_<name>.

Now comes the strange part ;-):

comtypes inspects the method parameter names to determine whether a
low-level or a high level method has been implemented.  Low-level
implementations MUST have a second parameter (self is the first) that
has the name 'this', high-level methods MUST have no second parameter
or it must have a different name.

To give an example:

Consider the ITypeLib::GetTypeInfo method.  The IDL signature would be:

    HRESULT GetTypeInfo( 
      [in] unsigned int  index,          
      [out] ITypeInfo FAR* FAR*  ppTInfo  
    );

The high-level comtypes implementation would be like this (assuming
that 'some_typeinfo' is a sequence of ITypeInfo pointers):

    def GetTypeInfo(self, index):
        return some_typeinfo[index]

and the low-level code would look like this:   


    def GetTypeInfo(self, this, index, pptinfo):
        pptinfo[0] = some_typeinfo[index]
        return S_OK

Events: The above description also applies to COM events.  A COM event
receiver is a COM interface implementation - the COM methods of the
interface are the event handlers that you implement.

Backwards (in)compatibility:
----------------------------

These changes are *mostly* backwards compatible, assuming that your
event handlers have a second parameter named 'this'.

An incompatibility occurs with VARIANT BYREF parameters.  Up to
comtypes 0.4.x, VARIANT BYREF parameters have been fully dereferenced
before they are passed to event handler implementations.

Since the new way requires that pointer-like objects are passed to low
level implementations, this cannot be done anymore.  An example of
this is the BeforeNavigate() event of InternetExplorer.  The C
signature of this method is:

   void BeforeNavigate(
       [in] IDispatch *pDisp,
       [in] VARIANT *url,
       [in] VARIANT *Flags,
       [in] VARIANT *TargetFrameName,
       [in] VARIANT *PostData,
       [in] VARIANT *Headers,
       [in, out] VARIANT_BOOL *Cancel
   );

Although only the last parameter is an [out] parameter (the others are
not), all are passed as byref params.  So, both the low-level and the
high-level method will, in comtypes 0.5, be called with VARIANT
instances containing BYREF values for the 2nd up to the 6th parameter.

In comtypes 0.4, the 2nd up to the 7th parameters would have been
passed as strings, integers, None, or bool.



That's enough blurb for now; any comments, and does the above make sense?

-- 
Thanks,
Thomas


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users

Reply via email to