Python COM - limit on size/complexity of returned object?

Discussion in 'Python' started by Paul Keating, Jun 24, 2004.

  1. Paul Keating

    Paul Keating Guest

    I have a very simple COM server written in Python that is trying to
    return a two-dimensional array 268 x 20. The values it contains are
    some small integers, some short (<29 character) Unicode strings, and
    None.

    To isolate the problem I have taken out the code that builds the
    matrix from real data, and just substituted a literal tuple of tuples,
    like this:

    class AtlasSecurity:
    _reg_progid_ = 'Arena.Security'
    ...
    def GetProfileComponentMatrixEx(self):
    # self.BuildMatrix()
    self.matrix = ((u'ID', u'Name', u'Type', .... ),
    ... )) # a 268-tuple of 20-tuples
    self.last_result = (self.matrix,)
    return self.last_result

    Because I was having trouble calling it from Excel ("the server has
    disconnected from its clients"), to see what was going on I decided to
    call it from a Python client, like this:

    from win32com.client import Dispatch
    x = Dispatch("Arena.Security")
    print x.GetProfileComponentMatrixEx()

    This blows up in python22.dll with a C++ Runtime abort(), no matter
    what I try. I can write a method that I can call 268 times to return
    the data one 20-element vector at a time. This works, but is really
    only good for simple data structures and I need this to work with
    structures of arbitrary complexity and levels of nesting.

    Is there a restriction on the size or complexity of the SafeArray that
    pythoncom is constructing from the returned value? Or what else am I
    doing wrong?

    (I am using Python 2.2 because I am working with embedded Python and
    that is the version that is embedded.)
    Paul Keating, Jun 24, 2004
    #1
    1. Advertising

  2. Michel Claveau/Hamster, Jun 24, 2004
    #2
    1. Advertising

  3. (Paul Keating) wrote in message news:<>...
    > I have a very simple COM server written in Python that is trying to
    > return a two-dimensional array 268 x 20. The values it contains are
    > some small integers, some short (<29 character) Unicode strings, and
    > None.
    >
    > To isolate the problem I have taken out the code that builds the
    > matrix from real data, and just substituted a literal tuple of tuples,
    > like this:
    >
    > class AtlasSecurity:
    > _reg_progid_ = 'Arena.Security'
    > ...
    > def GetProfileComponentMatrixEx(self):
    > # self.BuildMatrix()
    > self.matrix = ((u'ID', u'Name', u'Type', .... ),
    > ... )) # a 268-tuple of 20-tuples
    > self.last_result = (self.matrix,)
    > return self.last_result
    >
    > Because I was having trouble calling it from Excel ("the server has
    > disconnected from its clients"), to see what was going on I decided to
    > call it from a Python client, like this:
    >
    > from win32com.client import Dispatch
    > x = Dispatch("Arena.Security")
    > print x.GetProfileComponentMatrixEx()
    >
    > This blows up in python22.dll with a C++ Runtime abort(), no matter
    > what I try. I can write a method that I can call 268 times to return
    > the data one 20-element vector at a time. This works, but is really
    > only good for simple data structures and I need this to work with
    > structures of arbitrary complexity and levels of nesting.
    >
    > Is there a restriction on the size or complexity of the SafeArray that
    > pythoncom is constructing from the returned value? Or what else am I
    > doing wrong?
    >
    > (I am using Python 2.2 because I am working with embedded Python and
    > that is the version that is embedded.)


    Well, I did some testing with python 2.3 (that's what I have).
    Not sure if it will cheer you up, but I had no problems.

    - kv


    <server-code>
    class AtlasSecurity:
    _reg_clsid_ = '{92522CC6-05A5-4172-BFCA-56C65FD45467}'
    _reg_desc_ = 'Arena Server'
    _reg_progid_ = 'Arena.Security'

    _public_methods_ = ['GetProfileComponentMatrixEx']
    _public_attrs_ = []
    _readonly_attrs_ = []

    def GetProfileComponentMatrixEx(self):
    self.matrix = ((u'ID', u'Name', u'Type') * 10,) * 268
    self.last_result = (self.matrix,)
    return self.last_result


    if __name__ == '__main__':
    import win32com.server.register
    win32com.server.register.UseCommandLine(AtlasSecurity)
    </server-code>


    <python-client-code>
    import win32com.client

    from win32com.client import Dispatch
    x = Dispatch("Arena.Security")
    print x.GetProfileComponentMatrixEx()
    </python-client-code>

    <vb-client-code>
    Dim A As Object
    Set A = CreateObject("Arena.Security")

    Dim V As Variant
    Let V = A.GetProfileComponentMatrixEx()
    </vb-client-code>
    Konstantin Veretennicov, Jun 25, 2004
    #3
  4. Paul Keating

    Paul Keating Guest

    (Konstantin Veretennicov) wrote in message news:<>...

    > Well, I did some testing with python 2.3 (that's what I have).
    > Not sure if it will cheer you up, but I had no problems.


    Thanks for the pointer. I tried it on another machine with 2.3 and
    that works with no problems.

    And I made some further discoveries on the 2.2 side: the problem isn't
    a limit on the size of the returned object, it's cumulative. I amended
    GetProfileComponentMatrixEx() to return the first n rows of the
    matrix, to find out what the limit was: like this
    >>> print len(GetProfileComponentMatrixEx(10))

    10
    >>> print len(GetProfileComponentMatrixEx(40))

    40
    >>> print len(GetProfileComponentMatrixEx(80))

    <GPF!>
    But trying it repeatedly I found that I could only execute the
    following line once: it crashed calling it with an argument of 40 the
    second time:
    >>> print len(GetProfileComponentMatrixEx(40))

    40
    >>> print len(GetProfileComponentMatrixEx(40))

    <GPF!>
    And then I tried this repeatedly:
    >>> print len(GetProfileComponentMatrixEx(10))

    and -- surprise! -- it failed about the 7th or 8th invocation.

    So, now there are two possibilities.
    1. It's a 2.2 problem that is fixed in 2.3 (though I looked in
    Sourceforge for the bug reports and this did not show up there).
    2. It's a side-effect of the module I'm importing to do the actual
    work. On the machine running 2.3, I had to write a stub to represent
    this module, because it is a home machine that can't see the work
    server where the data is.

    If the DLL is at fault, I'm going to have a hard time convincing the
    vendor that they have to fix it. If I were them, I'd be sceptical. The
    DLL is loaded by the import statement, but in this test it is never
    called. It's hard to see what it's initialization code could possibly
    be doing to break pythoncom.
    Paul Keating, Jun 26, 2004
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ben Jessel
    Replies:
    2
    Views:
    6,137
    Sudsy
    Nov 26, 2003
  2. Mark Hahn

    pickle complexity limit?

    Mark Hahn, Nov 9, 2003, in forum: Python
    Replies:
    15
    Views:
    531
    Mark Hahn
    Nov 17, 2003
  3. Replies:
    1
    Views:
    1,065
    Victor Bazarov
    Jun 28, 2005
  4. Lionel B
    Replies:
    26
    Views:
    1,033
    P.J. Plauger
    Feb 3, 2007
  5. Ioannis Vranos

    C++ 0x size and complexity

    Ioannis Vranos, Feb 17, 2009, in forum: C++
    Replies:
    18
    Views:
    1,368
    Ioannis Vranos
    Feb 20, 2009
Loading...

Share This Page