Matt Wilbur schrieb:
> I may be saved.  I'm still not sure exactly why, though.

My explanation will follow.

> After some desperate tracing, I found something that works ( I found an 'if'
> statement when calling the method which always went down one path when I
> passed in an LP_LP_c_double instance.  I forced it down the other path by
> passing in an instance of LP_SAFEARRAY_c_double, as shown below):
> 
>>> import ctypes
>>> import comtypes.safearray as safearray
>>> safearray
<module 'comtypes.safearray' from
'C:\Python25\lib\site-packages\comtypes\safearray.pyc'>
>>> itrace = bench.SA.Traces[u'Trace1']
>>> itrace
<POINTER(IIviSpecAnTrace) ptr=0x2216610 at 107a8a0>
>>> AmplitudeType = safearray._midlSAFEARRAY(ctypes.c_double)
>>> AmplitudeType
<class 'ctypes.LP_SAFEARRAY_c_double'>
>>> amplitude = AmplitudeType()
>>> amplitude
<ctypes.LP_SAFEARRAY_c_double object at 0x00FB3DF0>
>>> itrace.FetchY(amplitude)
<ctypes.LP_SAFEARRAY_c_double object at 0x00FB3DF0>
> 
> and amplitude.unpack() gives me what I was looking for all along.

The intent of comtypes is that you can pass a sequence (list/tuple)
of integers when a SAFEARRAY* of integers is expected by a COM method.
This actually works (but only for [in] parameters, not for [in, out] 
parameters).

How does it work?
When you pass some Python object 'value' as argument to a COM method, the 
required 
argument type's .from_param(value) classmethod is called with this object, and
the result is passed to the raw COM method.

Usually the .from_param(value) implementation checks if 'value' already is an 
instance
of the required type, if so it is used unchanged.  If it is not (for example, 
'value' is
a sequence when a SAFEARRAY is required) then .from_param() calls a conversion 
function
which will usually build the required ctype from it.

So far, so good.

With [in, out] parameters additional processing of arguments is required.  
comtypes
(actually ctypes) scans the arguments passed to a function/method call,
marks [in, out] parameters, and constructs and marks [out] parameters so that
the return value can be retrieved from them after the COM method call has been 
done.

The problem/bug is that the processing for [in, out] parameters is in the wrong 
order.
First the marking of [in, out] parameters is done, after that the .from_param() 
conversion
is done.  This is the wrong order, because the return value(s) must be 
retrieved from
the converted parameters, not from the unconverted ones.  So, this is a ctypes 
bug
which can only be fixed in the next Python version (2.6, and hopefully in the 
next
2.5.3 release).

I hope that is is possible to build a workaround into comtypes so that it works 
as expected
with the current Python/ctypes version.

Fortunately Matt found a workaround that can even be used *now*:
[in, out] parameters should not be passed as normal Python objects (tuple, list 
for SAFEARRAY),
but as instances of the required argument type as he posted above.

Hopefully this workaround will also solve Mustafa's problem; see the post titled
'Create a SAFEARRAY with COM pointer by reference'.

-- 
Thanks,
Thomas


-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft 
Defy all challenges. Microsoft(R) Visual Studio 2008. 
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users

Reply via email to