"Universal Gateway"

Thomas Heller thomas.heller at ion-tof.com
Tue Nov 5 08:06:55 EST 2002


> Paul Moore:
> 
> > If so, is there a way to *call* an arbitrary interface?
> > (Actually, I imagine that this should be possible using calldll plus a
> > reasonable amount of arcane pointer arithmetic, but it sounds like it
> > could be a bit messy and error prone...)
> 
>    Looks like my posts that include attachments are no longer propagating.
> 
> Bruce Dodson:
> 
> > I, too, salivated when I first heard about universal gateway.  However, on
> > closer inspection, I found that it is outbound only: while it will allow
> you
> > to _implement_ just about any arbitrary interface in a Python server, it
> > will not allow your Python code to _access_ those custom interfaces as a
> > client.
> 
> "Neil Hodgson" <nhodgson at bigpond.net.au> writes:
>    Way back in 1997, I published some very low level code for calling
> arbitrary COM vtable interfaces using calldll on the Pythonwin sig mailing
> list and it is visible at
> http://groups.yahoo.com/group/pythonwin-sig/message/490
>    Unfortunately the yahoo interface flattens the code and calldll has
> changed since then, and ni has gone away :-( , so the code, resurrected
> a bit, is at the end of this post and available from
> http://www.scintilla.org/COMVtable.py
>    You can get copies of calldll and npstruct for Python 2.2 from
> http://www.activestate.com/PPMPackages/PyPPM/2.2+/packages/
> 
>    It is a very ugly way to do COM.

I have an experimental calldll/npstruct enhancement/replacement
module at http://starship.python.net/crew/theller/ctypes.html.

With this module available, and an additional com foundation
which is included in it's test directory, Neil's sample
can be written in this way:

------snip------
from ctypes import windll, POINTER, Structure, byref, WinError
from ctypes import c_int

ole32 = windll.ole32

from COM import GUID, IUnknownPointer, IUnknown

GUID_StdPicture = GUID("{00000316-0000-0000-C000-000000000046}")

# prototype for CoCreateInstance
ole32.CoCreateInstance.argtypes = [POINTER(GUID), c_int, c_int,
                                   POINTER(GUID),
                                   POINTER(IUnknownPointer)]

class IOleObject(IUnknown):
    _iid_ = GUID("{00000112-0000-0000-C000-000000000046}")
    _com_methods_ = IUnknown._com_methods_ + \
                    """SetClientSite GetClientSite SetHostNames Close
                    SetMoniker GetMoniker InitFromData
                    GetClipboardData DoVerb EnumVerbs Update
                    IsUpToDate GetUserClassID GetUserType SetExtent
                    GetExtent Advise Unadvise EnumAdvise GetMiscStatus
                    SetColorScheme""".split()

class IOleObjectPointer(IUnknownPointer):
    _interface_ = IOleObject


pobj = IOleObjectPointer()

result = ole32.CoCreateInstance(byref(GUID_StdPicture),
                                0,
                                1, # CLSCTX_INPROC_SERVER
                                byref(pobj._interface_._iid_),
                                byref(pobj)
                                )
if result:
    raise WinError(result)

print "IsUpToDate?", pobj.IsUpToDate()
print "Update", pobj.Update()
------snip------
When executed, this script prints:

IsUpToDate? 0
Update
Traceback (most recent call last):
  File "<stdin>", line 41, in ?
  File "COM.py", line 118, in func
    return call_commethod(self, index, args)
WindowsError: [Errno -2147221493] Object is static; operation not allowed

I didn't advertise my ctypes module, because the documentation is not
yet complete, and I probably don't have the time to support it.

Thomas



More information about the Python-list mailing list