comtypes
comtypes copied to clipboard
Attributeerror thrown when mixing intout + out parameters
Here is a C++ declaration for a method of a COM object:
virtual HRESULT STDMETHODCALLTYPE InitEx(
/* [in] */ long side,
/* [out][in] */ IMemory __RPC_FAR *__RPC_FAR *control,
/* [retval][out] */ long __RPC_FAR *rval
) = 0;
My problem is with the second parameter. It is an IMemory object (interface) passed by reference. This method can be called from C++ the following way:
CComPtr<IMemory> mem;
long ret,side;
HRESULT hr;
side = 1;
hr = m_Obj->InitEx(side,&mem,&ret);
You see, the mem object was not initialized. It does not need to be, because the method actually outputs a value there. But it was declared as an [out][in] parameter, and apparently I'm not able to call it from comtypes:
mem = prg.InitEx(1)
File "C:\Python36-32\lib\site-packages\comtypes\__init__.py", line 659, in call_with_inout
return rescode.__ctypes_from_outparam__()
AttributeError: 'tuple' object has no attribute '__ctypes_from_outparam__'
This question might be related to issue #87 , but that was already fixed.
I could actually fix this problem by changing this line of code:
https://github.com/enthought/comtypes/blob/master/comtypes/init.py#L659
into this:
if len(outargs) == 1 and not (isinstance(rescode,tuple)): # rescode is not iterable
return rescode.__ctypes_from_outparam__()
And then:
mem, retcode = prg.InitEx(1)
But I believe this might not be the correct way to do this. I'm not an expert in this field, so I did not post a pull request yet. An example use case and the solution is provided here, anyway.
Can somebody please confirm that this is a bug, and this is the correct way to fix it?
Thanks.
Have the same problem and fixed for now with the above suggestion. Would be nice to confirm it does not affect anything else.
Think about this: if rescode is a tuple, then this line:
return rescode.__ctypes_from_outparam__()
will certainly fail, because tuples do not have a __ctypes_from_outparam__ method. My opinion is that this change cannot affect any program code that was working before. I wanted to send a PR, but first I wanted at least one more person to confirm that this is good.
I could actually fix this problem by changing this line of code:
https://github.com/enthought/comtypes/blob/master/comtypes/init.py#L659
into this:
if len(outargs) == 1 and not (isinstance(rescode,tuple)): # rescode is not iterable return rescode.__ctypes_from_outparam_
The URL no longer points to the mentioned codebase. Rewriting it with a permalink, it would probably be here.
https://github.com/enthought/comtypes/blob/d70eb4aabff0941db1b97d1af0b8d61037c200b3/comtypes/init.py#L659-L660
An old bug regarding the in out parameter was resolved in #473, but I'm unclear how it affects this yet.