Hello,

I'm the current maintainer of PyDbgEng and recently started adding
support for comtypes >= v0.5.1.  After fixing up all my events I ran
into this issue:

My interface is defined as shown below.  The OUT param "Frames" is
actually an array.  However, in call_with_inout an exception is thrown
if the type is passed in as an LP.  I added some code to work around the
issue (which seems to work okay).  This all worked a-okay in the older
0.4 series.

Love to know if this is a bug or if I'm doing things wrong :)  If it is
a bug it would be good to see a new release that addresses it.


Interface:
---------

HRESULT
  IDebugControl::GetStackTrace(
    IN ULONG64  FrameOffset,
    IN ULONG64  StackOffset,
    IN ULONG64  InstructionOffset,
    OUT PDEBUG_STACK_FRAME  Frames,
    IN ULONG  FramesSize,
    OUT OPTIONAL PULONG  FramesFilled
    );


Calling code:
------------

def get_stack_trace(self, frames_count):
    try:
        frames_buffer = (DbgEng._DEBUG_STACK_FRAME * frames_count)()
        frames_buffer_ptr = cast(frames_buffer,
POINTER(DbgEng._DEBUG_STACK_FRAME))

        self.idebug_control.GetStackTrace(0, 0, 0, frames_buffer_ptr,
            frames_count)


        frames_list = []
        for i in range(frames_count):
            address_of_frame_buffer = (addressof(frames_buffer) +
i*sizeof(DbgEng._DEBUG_STACK_FRAME))
            frame = DbgEng._DEBUG_STACK_FRAME.from_address(
address_of_frame_buffer )
            frames_list.append( frame )

        return frames_list
    except:
        import traceback
        traceback.print_exc()
        raise


Original comtypes code (partial just showing offending lines):
-------------------------------------------------------------

if type(atyp) is SIMPLETYPE:
    # The from_param method of simple types
    # (c_int, c_double, ...) returns a byref()
    # object which we cannot use since later
    # it will be wrapped in a pointer.  Simply
    # call the constructor with the argument
    # in that case.
    v = atyp(v)
else:
    # Added some debug output...
    print "call_with_inout:", argtypes[i]
    print "call_with_inout:", argtypes[i]._type_
    print "call_with_inout:", v._type_
    print "call_with_inout:", v._type_ == argtypes[i]._type_

    # Things blow up here
    v = atyp.from_param(v)
    assert not isinstance(v, BYREFTYPE)

call_with_inout: <class 'ctypes.LP__DEBUG_STACK_FRAME'>
call_with_inout: <class
'comtypes.gen._95F974F5_B0AE_44A4_8EB9_FEC4E8136416_0_0_
0._DEBUG_STACK_FRAME'>
call_with_inout: <class
'comtypes.gen._95F974F5_B0AE_44A4_8EB9_FEC4E8136416_0_0_
0._DEBUG_STACK_FRAME'>
call_with_inout: True
Traceback (most recent call last):
  File "C:\Python25\lib\site-packages\PyDbgEng\PyDbgEng.py", line 603,
in get_st
ack_trace
    frames_count)
  File "C:\Python25\lib\site-packages\comtypes\__init__.py", line 599,
in call_w
ith_inout
    v = atyp.from_param(v)
TypeError: expected _DEBUG_STACK_FRAME instance instead of
LP__DEBUG_STACK_FRAME

<type 'exceptions.TypeError'>


Code change:
-----------

if type(atyp) is SIMPLETYPE:
    # The from_param method of simple types
    # (c_int, c_double, ...) returns a byref()
    # object which we cannot use since later
    # it will be wrapped in a pointer.  Simply
    # call the constructor with the argument
    # in that case.
    v = atyp(v)
else:

    if not v._type_ == argtypes[i]._type_:
        v = atyp.from_param(v)
        assert not isinstance(v, BYREFTYPE)



- mike

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
comtypes-users mailing list
comtypes-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/comtypes-users

Reply via email to