enthought / enthought/comtypes

Attributeerror thrown when mixing intout + out parameters

Open
#131 3 comments 1 reaction 0 assignees View on GitHub
help wanted
Dominant language
Python
Stars
345
Forks
105
PR merge metrics
No merged PRs in 30d

Description

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 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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.