Mailing List Archive

Python and COM (long)
Bill Tutt <billtut@microsoft.com> wrote:

(posted and cc'ed to bill)

>> From: htrd90@zepler.org [mailto:htrd90@zepler.org]
>>
>> Bill Tutt <billtut@microsoft.com> wrote:
>>
>> >(As an added bonus, this should actually work)
>> >The only GUID from interp.py is the coclass one. Every other
>> GUID was just
>> >generated.
>>
>> I _think_ the python code would also need to be changed to allow
>> QueryInterface for the IID of that dispinterface.
>
>Nope. Dispinterfaces are wierd in that they only tell you whats available
>via the IDispatch interface.

Argh - this com terminology is a persistant pain. Certainly it is an
IDispatch interface. The tricky question is whether it is the
IDispatch interface returned by QueryInterface for IID_IDispatch, or a
_different_ IDispatch returned by QueryInterface for
IID_IPythonInterpreter (in this case)

>You have to do a QI for IDispatch, not the
>dispinterface.

OK, that clarifies your meaning.


Bill's advice is something I've heard before, but it contradicts my
experience. I thought I would try some experiments with this object
and some other Automation controllers. The results were mixed, and a
little disturbing.....

For the first tests I followed Bill's recommendations. I compiled the
.idl, registered the .tlb, and manually patching the TypeLib section
of the "Python.Interpreter" object to point to our new LIBID.

Testing the object in this state, VB6 and the COM Object Viewer (ver
2.10.054), produce negative results. VB produces "Run-time error 430"
"Class does not support Automation or does not support expected
interface". The object viewer creates the object but does not list
IPythonInterpreter.

Instrumenting the com server with the method below makes it clear that
both controllers are querying for IID_IPythonInterpreter, and not
IID_IDispatch.
def _query_interface_(self, iid):
print iid
return 0

However, VC6 (sp1) using #import works well with this object. It is
querying for IID_IDispatch, as predicted by Bill, and never
IID_IPythonInterpreter.


For the second set of tests, I added the following implementation of
QueryInterface, as I originally thought was necessary.
def _query_interface_(self, iid):
print iid
if str(iid)=="{EB048AA4-C2D1-11D2-855D-00C04F797DBA}":
return win32com.server.util.wrap(self)
return 0

This fixes VB and the Object Viewer (which now correctly lists
IPythonInterpreter). VC6 still works.


So, my conclusion is that you need to support QueryInterface for
_both_ the IID of your dispinterface and IID_IDispatch, and that they
must both return the same implementation of IDispatch.

Comments _really_ appreciated. Thanks for reading,



Toby Dickenson
Python and COM (long) [ In reply to ]
Toby Dickenson wrote in message <378d8ee2.10645225@news.freeserve.net>...
>Bill Tutt <billtut@microsoft.com> wrote:
>
...
>So, my conclusion is that you need to support QueryInterface for
>_both_ the IID of your dispinterface and IID_IDispatch, and that they
>must both return the same implementation of IDispatch.

I wish I had time to dig the thread up (in the pycom-dev archives) and
ensure I am not talking crap, but this also appears to be consistent with
how you must work with multiple dispatch interfaces - with fear of being
totally wrong, I seem to recall we must change win32com in that situation to
explicitely QI for the dispinterface, as a QI for IDispatch may not give us
the IDispatch we are after...

[This is still a pending win32com change too]

Mark.