Dominik . wrote:
>
> I’m trying to control an existing COM server (C++ code) with a python
> COM client.
>
> Unfortunately, no type library exists for most of the COM objects.
> Thus I’m restricted to the dynamic dispatch implementation.
>
Do you have an IDL file or a C++ header file? It might be possible for
you to build a type library.
Dynamic dispatch has rather strict rules on the data types and parameter
usages. Many C++ programmers totally disregard those rules, and treat a
COM interface as if it were a simple pure virtual base class. It's not
hard to build C++ interfaces that cannot be called dynamically.
>
> This is my sample code. Its equivalent works flawlessly when called
> via VBA, moreover I'm sure that the requested COM methods exist in the
> server.
>
> import win32com.client
>
> obj_1 = win32com.client.DispatchEx(“MyCOMServerApplication”)
>
> obj_2 = obj_1.NewDocument() # works, returns a new dynamic dispatch
> (<CDispatch: None>)
>
> obj_2.SubObject.DoSomething(“MyArgument”) # works, but only if I don’t
> step into it (i.e. into CDispatch.__getattr__)
>
> #obj_2.GetSomeNumber() # TypeError: 'int' object is not callable
>
> obj_2.GetSomeNumber # works correctly, but only if I don’t step into
> it (i.e. into CDispatch.__getattr__)
>
This suggests that GetSomeNumber is being interpreted as a property.
> obj_2.DoSomething(“MyArgument”) # doesn’t work
>
What is the C++ signature of this method?
> Evidently I’m very confused, especially since the behavior differs
> when stepping into the relevant python code.
>
Yeah, don't do that. There's a fair amount of magic going on in the COM
glue.
> I have also read that the dynamic dispatch implementation doesn't
> support by-ref parameters, is this information still up to date?
>
Pretty much. The C++ implementation is expected to identify one or more
[output] parameters. The Python wrapper will return those values. You
don't pass a location for them. So, if you have a method to compute the
product and average of two numbers:
HRESULT TimesAndAverage( long one, long two, long * prod, long * avg );
If it is declared correctly in the server, you would call it from Python as:
(res, prod, avg) = iface.TimesAndAverage( 3, 4 )
--
Tim Roberts, [email protected]
Providenza & Boekelheide, Inc.
_______________________________________________
python-win32 mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-win32