COM Question - QueryInterface?

Toby Dickenson htrd90 at zepler.org
Thu Jun 10 16:07:40 EDT 1999


(posted and cced to Chris)

Chris Tavares <tavares at connix.com> wrote:

>Thanks. The reason that the interface in question isn't a dual is because my
>object design depends quite heavily on having multiple interfaces. If you have
>multiple duals, you end up with lots of problems with IDispatch, since you can't
>safely implement more than one version of the same interface on a single object
>(and lots of people have tried, REALLY HARD).

This is a fallacy about IDispatch that I've heard from many sources, but it
certainly is not true.

One true statement is that you can only have one interface known as
IID_IDispatch. This causes a problem for scripting languages that can not
QueryInterface (or, worse, which QueryInterface behind your back).[

If you need to support this kind of client (VBScript, JScript, what else?
definitely not Python) then you need to implement IID_IDispatch with the union
of the methods from all your other interfaces. The page Chris mentions (below)
has a great summary of some solutions to this.

>So what I'm doing is having multiple oleautomation compatible interfaces, and then
>using a typelib-driven IDispatch implementation that I got from
>http://www.sellsbrothers.com/tools/multidisp/index.html. This automagically merges
>all my separate interfaces into a pseudo-object model. Really neat stuff, and
>saves a TON of work.

Follow that advice if you need to support those lesser scripting clients, or
don't if you don't.

In any case, there is still no reason not to make all your other interfaces dual
too. This should be an easy step. I am assuming you already have some IDL for
these interfaces? Change the oleautomation line to dual, and hook up the same
typelib-driven IDispatch implementation you are already using for IID_Dispatch.
If you are using ATL for this implementation then it all comes for free. The
advantages? You get easier access from Python, and in VB you get compile time
type safety.

In your specific example, the type library would say your collection object's
Item method returns an ITavaresDrive (or whatever) and python would use an
appropriate makepy-generated wrapper.

>Having tried that, I find that I now have access to IDispatch::Invoke. Well, what
>I really wanted was win32com.client.dynamic.Dispatch. How do I get to the wrapped
>IDispatch rather than the raw one?

drive = drives.Item("c:")._oleobj_.QueryInterface(pythoncom.IID_IDispatch)
win32com.client.Dispatch(drive)

(from memory)

I hope this helps,


Toby Dickenson




More information about the Python-list mailing list