Win32Com: VB5 COM server gotchas 
Author Message
 Win32Com: VB5 COM server gotchas

FWIW

Visual Basic 5 treats all string parameters to method calls as [in/out]
parameters (unless they are preceded by the incantation 'ByVal' in the
method declaration) in the type libraries it generates. This can be seen by
inspecting the type library of a dll/exe with the OLE/COM viewer (which
generates an IDL file from the type library. This doesn't cause any
problems in using the com server from vb -- but, in python it can
drasitically change the value returned as the return value of the call.
Specifically, if one is attempting to return an IDispatch pointer of an
object in the server makepy.py will see the [in/out] parameters and
generate code which when invoked returns a tuple (consisting of a
'PY_IDispatchptr xxxx with object at yyyy' followed by the values of the
input parameters) rather than the desired value: an instance of the class
the IDispatch belongs to.

I don't know what other variable types in VB need to be treated with the
'ByVal' antecedent for correct behavior. This behavior is benign when
called from vb clients ( in use for 18 months). Presumably, 'C' and other
languages with pointer or reference variables would also accept this
behavior from a vb com server.

I assume the conversion of [in/out] parameters to items in a returned tuple
follows the pattern that was established by SWIG and for the same reasons.
In the case above (where the desired return value is an instance of a
class) why is the first item in the tuple a  'PY_IDispatchptr xxxx with
object at yyyy'  rather than said instance? In that case one could extract
the first tuple item and proceed as desired. Currently, one has to (have
access to the source and ) correct the vb code and recompile the server.

MAM



Tue, 08 Feb 2000 03:00:00 GMT  
 Win32Com: VB5 COM server gotchas

Quote:
>Visual basic 5 treats all string parameters to method calls as [in/out]
>parameters (unless they are preceded by the incantation 'ByVal' in the
>method declaration) in the type libraries it generates. This can be seen by
>inspecting the type library of a dll/exe with the OLE/COM viewer (which
>generates an IDL file from the type library. This doesn't cause any
>problems in using the com server from vb -- but, in python it can
>drasitically change the value returned as the return value of the call.
>Specifically, if one is attempting to return an IDispatch pointer of an
>object in the server makepy.py will see the [in/out] parameters and
>generate code which when invoked returns a tuple (consisting of a
>'PY_IDispatchptr xxxx with object at yyyy' followed by the values of the
>input parameters) rather than the desired value: an instance of the class
>the IDispatch belongs to.

Yes - all of the above is quite correct.  It is also correct there is a
"buglet" :-) in win32com, in that the "PyIDispatch at xx with obj at yyy"
should be a class instance.

I assume you are using a makepy generated file?  AFAIK, this is what makes
that assumption about the return object.  In the generated file (and in
win32com\client\dynamic.py) there is a _get_good_object_ function which does
the conversion - this doesnt handle tuple return values - quite a trivial
change - just not done yet.

Quote:
>I don't know what other variable types in VB need to be treated with the
>'ByVal' antecedent for correct behavior. This behavior is benign when
>called from vb clients ( in use for 18 months). Presumably, 'C' and other
>languages with pointer or reference variables would also accept this
>behavior from a vb com server.

The "problem" here is that because VB has declared the variable as "in/out",
Python must assume that the parameter changed (or at least could
change!)during the call.

And as Python itself has no concept of "call by reference", there is really
no choice but to return a tuple in this situation.

So there is really nothing wee can do about this situation.  It is a clash
between "VB's default variable calling convention is ByRef" and "Python cant
handle 'pass by ref'".

But it is consistant, once you understand the rules :-)

Quote:
>I assume the conversion of [in/out] parameters to items in a returned tuple
>follows the pattern that was established by SWIG and for the same reasons.
>In the case above (where the desired return value is an instance of a
>class) why is the first item in the tuple a  'PY_IDispatchptr xxxx with
>object at yyyy'  rather than said instance? In that case one could extract
>the first tuple item and proceed as desired. Currently, one has to (have
>access to the source and ) correct the vb code and recompile the server.

Nothing to do with SWIG at all, and the fact that an instance is not in the
tuple is a small, but definate bug.  I'll try and remember to fix it...

Mark.



Wed, 09 Feb 2000 03:00:00 GMT  
 Win32Com: VB5 COM server gotchas

Thanks for the confirmation of the situation. BTW, I was completely baffled
by what was going on until I started to look at the IDL generated from
various type libraries. The MS 'OLE-COM object viewer' has evolved into a
most useful tool for spelunking COM code. Particularly for segregating
anomolous behavior between client and server 'apps'. I.e., if two server
type libraries transformed to IDL have the same structure and two clients
treat them differently --> the problem is in at least one of the clients.
If the two servers transformed type libraries don't have the same structure
--> at least one of the servers is doing something different (perhaps
inadvertantly).

The reference to SWIG should have been clearer -- I didn't mean to suggest
that win32com (et al) utilized SWIG or was derivative from it. Chapter 9 of
the SWIG User's Guide ver. 1.1 has a section starting on page 196 'Using
typemaps to return arguments':

"A common problem in some C programs is that values may be returnde in
arguments rather than in the return value of a function....

...we first check to see if any result exists. If so, we turn it into a
list and append our new output value to it. If this is the only result, we
simply return it normally. For our sample function, there are three output
values so the function will return a list of three elements."

This elision is not terribly clear, but I think you can see that the
handling of 'out' parameters in SWIG encapsulated C code is quite like the
way win32com handles 'in/out' parameters in com calls.

MAM

Quote:
>The "problem" here is that because VB has declared the variable as "in/out",
>Python must assume that the parameter changed (or at least could
>change!)during the call.

>And as Python itself has no concept of "call by reference", there is really
>no choice but to return a tuple in this situation.

>So there is really nothing wee can do about this situation.  It is a clash
>between "VB's default variable calling convention is ByRef" and "Python cant
>handle 'pass by ref'".

>But it is consistant, once you understand the rules :-)

>>I assume the conversion of [in/out] parameters to items in a returned tuple
>>follows the pattern that was established by SWIG and for the same reasons.
>>In the case above (where the desired return value is an instance of a
>>class) why is the first item in the tuple a  'PY_IDispatchptr xxxx with
>>object at yyyy'  rather than said instance? In that case one could extract
>>the first tuple item and proceed as desired. Currently, one has to (have
>>access to the source and ) correct the vb code and recompile the server.

>Nothing to do with SWIG at all, and the fact that an instance is not in the
>tuple is a small, but definate bug.  I'll try and remember to fix it...

>Mark.

life is just a chair of bowlies..


Wed, 09 Feb 2000 03:00:00 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Unable to use win32com on Ecco COM server despite success with VB and Perl COM

2. win32com COM-server and py2exe

3. how to register COM interface from python COM-server

4. Catch COM events generated by a Python COM server with Visual Basic

5. Fortran numerical server using Com server wizard.

6. Can't See My COM Server in COM Browser

7. COM server in python - howto restart server

8. win32com: get error 80004005 in attempt to use a pythom COM serve r

9. win32com: raising com-event

10. win32com, COM, MediaPlayer

11. HELP! win32com, COM, Invoke problem

12. Using COM objects as dictionaries in win32com.

 

 
Powered by phpBB® Forum Software