Assing a COM Interface to a Python object for callbacks

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Mikko Ohtamaa

    Assing a COM Interface to a Python object for callbacks

    Hi,

    I am quite new to Python, PythonCom and COM generally. As a former
    Java programmer, I have found Python's flexible ability to access
    native Win32, especially COM, very comfortable. However, there is
    quite little on-line documentation and examples available about
    PythonCOM. The only good sources I have found were the sample chapter
    from Mark Hammond's book and some decades old PowerPoint show.

    I have a following problem:

    I am trying to do XML Schema validation using MSXML SAX parser through
    PythonCOM API.

    MSXML offers two different interfaces for SAX: One for VB and one for
    C++. C++ one is named ISAXXMLReader and VB one is named
    IVBSAXXMLReader . I haven't found what is the basic difference between
    these interfaces though I have carefully read MSXML SDK documentation.
    I assume IVBSAXXMLReader might have some IDispatch functionality which
    is requirement for PythonCom(?).

    The problem is that SAX Parser requires COM interface for callback.
    You must assign a COM interface as a handler to the parser. When the
    parsing begins, the handler calls this interface.

    saxReader.error Handler = myErrorHandler <-- COM Interface

    I do not know how to turn Python class into COM interface on the fly.

    I have managed to open the C++ version ISAXXMLReader of the interface.
    I have NOT succeed to do this for VB versioon IVBSAXXMLReader , because
    I do not know how it happens. I assume you have to use
    CoCreateInstanc e, but it returns "Class not registered", see the
    sample below.

    After opening ISAXXMLReader I have not been able to pass COM error
    handler for it. I have reasons not to go through full process
    registering my own error handler as a COM server into Windows registry
    and create it using win32com.client .Dispatch("Pyth on.MyErrorHandl er").
    Is there a way to create COM server on the fly and get the COM handle
    for it? I have been trying to read win32.client and win32.server
    Python sources and even PythonCOM C sources, but unfortunately my
    skillz are not 1337 enough to see the big picture.

    How to assign a COM Interface for a Python object? It goes somehow
    through policies and wrapping, right? Unfortunately every approach I
    have tried end to an error saying my wrapper IPyDispatch cannot be
    used as ISAXErrorHandle r.

    Mikko Ohtamaa
    Student of Industrial Engineering & Management
    Oulu, Finland

    Sample code:

    class MySaxErrorHandl er:

    # Some random stuff in stucked into this class
    # hoping it would help policies & wrapping
    _reg_progid_ = "Art2ComponentV alidator.SaxErr orHandler"
    _reg_clsid_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
    _reg_clsctx_ = "INPROC_SER VER"
    _com_interfaces = [ "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}" ]
    _query_interfac e_ = "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}"
    _public_methods _ = [ "error", "fatalError ", "ignorableWarni ng" ]

    # A piece of VB sample:
    #Private Sub IVBSAXErrorHand ler_error(ByVal oLocator As
    SXML2.IVBSAXLoc ator,

    strErrorMessage As String, ByVal nErrorCode As Long)
    # WriteErrorToRes ults "Error", strErrorMessage , _
    # nErrorCode, oLocator.lineNu mber, oLocator.column Number
    #End Sub

    def error(oLocator, strErrorMessage , nErrorCode):
    print strErrorMessage

    def fatalError(oLoc ator, strErrorMessage , nErrorCode):
    print strErrorMessage

    def ignorableWarnin g(oLocator, strErrorMessage , nErrorCode):
    print strErrorMessage

    def saxtest():

    # SAXXmlReader MIDL: a4f96ed0-f829-476e-81c0-cdc7bd2a0802
    # sax error handler: a60511c4-ccf5-479e-98a3-dc8dc545b7d0
    # ivbsaxerrorhand ler: d963d3fe-173c-4862-9095-b92f66995f52
    # ivbsaxxmlreader : 8c033caa-6cd6-4f73-b728-4531af74945f

    # test path switcher
    useISAX = 0

    if useISAX:
    # Use c++ version ISAXXMLReader
    saxReader = win32com.client .Dispatch("Msxm l2.SAXXMLReader .4.0")
    errorHandler = MySaxErrorHandl er()

    # ISAXErrorHandle r: a60511c4-ccf5-479e-98a3-dc8dc545b7d0

    iid = pywintypes.IID( "{a60511c4-ccf5-479e-98a3-dc8dc545b7d0}")

    # What I should do instead of this?
    saxReader.error Handler =
    win32com.server .util.wrap(erro rHandler, iid)

    # Following error:
    # File "C:\Python22\Li b\site-packages\win32c om\server\util. py",
    line 28, in wrap
    # ob = ob.QueryInterfa ce(iid) # Ask the PyIDispatch
    if it supports it?
    # pywintypes.com_ error: (-2147467262, 'No such interface
    supported', None, None)

    else:
    # Use VB version, IVBSAXXMLreader
    clsid = pywintypes.IID( "{8c033caa-6cd6-4f73-b728-4531af74945f}")
    iid = clsid
    create_as = win32com.client .pythoncom.CLSC TX_INPROC_SERVE R
    iface = win32com.client .pythoncom.CoCr eateInstance(cl sid,
    None, create_as, iid)
    # pywintypes.com_ error: (-2147221164, 'Class not registered',
    None, None)
  • Alan Kennedy

    #2
    Re: Assing a COM Interface to a Python object for callbacks

    Mikko Ohtamaa wrote:
    [color=blue]
    > I have a following problem:
    > I am trying to do XML Schema validation using MSXML SAX parser through
    > PythonCOM API.
    >
    > MSXML offers two different interfaces for SAX: One for VB and one for
    > C++. C++ one is named ISAXXMLReader and VB one is named
    > IVBSAXXMLReader . I haven't found what is the basic difference between
    > these interfaces though I have carefully read MSXML SDK documentation.
    > I assume IVBSAXXMLReader might have some IDispatch functionality which
    > is requirement for PythonCom(?).
    >
    > The problem is that SAX Parser requires COM interface for callback.
    > You must assign a COM interface as a handler to the parser. When the
    > parsing begins, the handler calls this interface.
    >
    > saxReader.error Handler = myErrorHandler <-- COM Interface
    >
    > I do not know how to turn Python class into COM interface on the fly.[/color]

    I'm not sure how Mark Hammond's Windows extensions handle this
    situation, if at all.

    But I do know that Thomas Heller's "ctypes" has a COM framework which
    addresses the problem. Only thing is, I don't know how robust the
    current support is, given that, in Thomas own words: "Warning: work in
    progress".



    HTH,

    --
    alan kennedy
    -----------------------------------------------------
    check http headers here: http://xhaus.com/headers
    email alan: http://xhaus.com/mailto/alan

    Comment

    • Alan Kennedy

      #3
      Re: Assing a COM Interface to a Python object for callbacks

      Mikko Ohtamaa wrote:
      [color=blue]
      > I have a following problem:
      > I am trying to do XML Schema validation using MSXML SAX parser through
      > PythonCOM API.
      >
      > MSXML offers two different interfaces for SAX: One for VB and one for
      > C++. C++ one is named ISAXXMLReader and VB one is named
      > IVBSAXXMLReader . I haven't found what is the basic difference between
      > these interfaces though I have carefully read MSXML SDK documentation.
      > I assume IVBSAXXMLReader might have some IDispatch functionality which
      > is requirement for PythonCom(?).
      >
      > The problem is that SAX Parser requires COM interface for callback.
      > You must assign a COM interface as a handler to the parser. When the
      > parsing begins, the handler calls this interface.
      >
      > saxReader.error Handler = myErrorHandler <-- COM Interface
      >
      > I do not know how to turn Python class into COM interface on the fly.[/color]

      I'm not sure how Mark Hammond's Windows extensions handle this
      situation, if at all.

      But I do know that Thomas Heller's "ctypes" has a COM framework which
      addresses the problem. Only thing is, I don't know how robust the
      current support is, given that, in Thomas own words: "Warning: work in
      progress".



      HTH,

      --
      alan kennedy
      -----------------------------------------------------
      check http headers here: http://xhaus.com/headers
      email alan: http://xhaus.com/mailto/alan

      Comment

      • John J. Lee

        #4
        Re: Assing a COM Interface to a Python object for callbacks

        Alan Kennedy <alanmk@hotmail .com> writes:
        [color=blue]
        > Mikko Ohtamaa wrote:[/color]
        [...][color=blue][color=green]
        > > The problem is that SAX Parser requires COM interface for callback.
        > > You must assign a COM interface as a handler to the parser. When the
        > > parsing begins, the handler calls this interface.[/color][/color]
        [...]

        See Mark Hammond's examples in the win32com/tests directory (IIRC)
        that win32all installs in your Python directory. I can't remember
        which example demonstrates this, but I'm pretty sure one does.
        There's also been some discussion on c.l.py on this.


        John

        Comment

        Working...