Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Attributeerror thrown when mixing intout + out parameters #131

Open
nagylzs opened this issue Aug 30, 2017 · 3 comments
Open

Attributeerror thrown when mixing intout + out parameters #131

nagylzs opened this issue Aug 30, 2017 · 3 comments
Labels
help wanted Extra attention is needed

Comments

@nagylzs
Copy link

nagylzs commented Aug 30, 2017

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.

@ravikumars
Copy link

Have the same problem and fixed for now with the above suggestion. Would be nice to confirm it does not affect anything else.

@nagylzs
Copy link
Author

nagylzs commented Dec 18, 2017

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.

@junkmd junkmd added the help wanted Extra attention is needed label Nov 27, 2022
@junkmd
Copy link
Collaborator

junkmd commented Jan 11, 2024

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.

if len(outargs) == 1:
rescode = rescode.__ctypes_from_outparam__()

An old bug regarding the in out parameter was resolved in #473, but I'm unclear how it affects this yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants