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