[ctypes-commit] ctypes/comtypes __init__.py,1.2,1.3
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2005-01-25 15:31:21
|
Update of /cvsroot/ctypes/ctypes/comtypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14171 Modified Files: __init__.py Log Message: Lots of changes. Index: __init__.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/comtypes/__init__.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** __init__.py 13 Jan 2005 09:34:45 -0000 1.2 --- __init__.py 25 Jan 2005 15:31:11 -0000 1.3 *************** *** 1,7 **** from ctypes import * - try: - HRESULT - except NameError: # ctypes 0.92 and older - from _ctypes import HRESULT from comtypes.GUID import GUID --- 1,5 ---- + # requires ctypes 0.9.3 or later + import new from ctypes import * from comtypes.GUID import GUID *************** *** 9,40 **** # The metaclasses... - # would c_void_p be a better base? Conflicts with the QueryInterface signature... - _pbase = POINTER(c_void_p) - #_pbase = c_void_p - - def _create_method_codestring(func, doc=None): - # Assuming the <func> has this definition: - # def func(self, first, second="spam", third=42): - # .... - # a string containing the following code is returned: - # def func(self, first, second="spam", third=42): - # return self.func._api_(self, first, second, third) - import inspect - args, varargs, varkw, defaults = inspect.getargspec(func) - if varkw: - raise TypeError, "%s argument list must not contain ** argument" % func.func_name - if doc: - return "def %s%s:\n %r\n return self.%s._api_%s" % \ - (func.func_name, - inspect.formatargspec(args, varargs, varkw, defaults), - doc, - func.func_name, - inspect.formatargspec(args, varargs, varkw)) - return "def %s%s:\n return self.%s._api_%s" % \ - (func.func_name, - inspect.formatargspec(args, varargs, varkw, defaults), - func.func_name, - inspect.formatargspec(args, varargs, varkw)) - class _cominterface_meta(type): # Metaclass for COM interface classes. --- 7,10 ---- *************** *** 43,63 **** methods = namespace.pop("_methods_", None) cls = type.__new__(self, name, bases, namespace) if methods: setattr(cls, "_methods_", methods) ! # The interface 'cls' is used as a mixin for the ! # POINTER(interface) class: ! def __del__(s_): ! "Release the COM refcount we own." ! if s_: ! result = s_.Release() ! ## def __eq__(s_, other): ! ## return cast(s_, c_int).value == cast(other, c_int).value ! # POINTER(interface) looks nice as class name, but is it ok? ! p = _compointer_meta("POINTER(%s)" % cls.__name__, ! (cls, _pbase), ! {"__del__": __del__, ! ## "__eq__": __eq__, # XXX fixme: COM identity rules ! "_type_": c_int # XXX fixme ! }) from ctypes import _pointer_type_cache _pointer_type_cache[cls] = p --- 13,25 ---- methods = namespace.pop("_methods_", None) cls = type.__new__(self, name, bases, namespace) + # XXX ??? First assign the _methods_, or first create the POINTER class? + # or does it not matter? if methods: setattr(cls, "_methods_", methods) ! # The interface 'cls' is used as a mixin. ! # XXX "POINTER(<interface>)" looks nice as class name, but is it ok? ! p = type(_compointer_base)("POINTER(%s)" % cls.__name__, ! (cls, _compointer_base), ! {}) from ctypes import _pointer_type_cache _pointer_type_cache[cls] = p *************** *** 68,95 **** if name != "_methods_": return ! self.make_methods(value) ! ! def __get_method(self, name): ! # should create a method if doesn't have one. ! mth = getattr(self, name, None) ! if mth is None: ! def func(self, *args): ! return getattr(self, name)._api_(self, *args) ! setattr(self, name, func) ! # convert into unbound method ! mth = getattr(self, name) ! return mth ! ! func = mth.im_func ! if len(func.func_code.co_code) == 4: ! # method has no body - create one ! codestring = _create_method_codestring(func, func.func_doc) ! ns = {} ! exec codestring in ns ! func = ns[func.func_name] ! # convert into unbound method ! setattr(self, name, func) ! mth = getattr(self, name) ! return mth def __get_baseinterface_methodcount(self): --- 30,34 ---- if name != "_methods_": return ! self._make_methods(value) def __get_baseinterface_methodcount(self): *************** *** 98,121 **** for itf in self.__mro__[1:]]) ! def make_methods(self, methods): ! if not methods: ! return vtbl_offset = self.__get_baseinterface_methodcount() for i, (restype, name, argtypes) in enumerate(methods): # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! # the actual COM interface method object, will invoke ! # the method in the VTable of the COM interface pointer ! func = prototype(i + vtbl_offset, name) ! ! # the Python method implementation in the interface ! mth = self.__get_method(name) ! mth.im_func._api_ = func ! # This class only to avoid a metaclass confict. No additional ! # behaviour here. ! class _compointer_meta(type(_pbase), _cominterface_meta): pass ################################################################ --- 37,72 ---- for itf in self.__mro__[1:]]) ! def _make_methods(self, methods): vtbl_offset = self.__get_baseinterface_methodcount() for i, (restype, name, argtypes) in enumerate(methods): # the function prototype prototype = WINFUNCTYPE(restype, *argtypes) ! # create a bound method, which will call into the COM vtbl ! # the three-argument call requires ctypes 0.9.3 ! mth = prototype(i + vtbl_offset, name, self) ! impl = getattr(self, name, None) ! if impl is None: ! setattr(self, name, mth) ! else: ! mthname = "_%s__com_%s" % (self.__name__, name) ! # attach it with a private name (__com_AddRef, for example) ! setattr(self, mthname, mth) ! # metaclass for COM interface pointers ! class _compointer_meta(type(c_void_p), _cominterface_meta): pass + # base class for COM interface pointers + class _compointer_base(c_void_p): + __metaclass__ = _compointer_meta + def __del__(self): + "Release the COM refcount we own." + if self.value: + self.Release() + def __eq__(self, other): + if not isinstance(other, _compointer_base): + return False + return self.value == other.value + ################################################################ *************** *** 123,154 **** def STDMETHOD(restype, name, argtypes=()): ! "Defines a COM method" return restype, name, argtypes ! class IUnknown(object): __metaclass__ = _cominterface_meta _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") def QueryInterface(self, interface): "QueryInterface(klass) -> instance" p = POINTER(interface)() ! self.QueryInterface._api_(self, byref(interface._iid_), byref(p)) return p def AddRef(self): "Increase the internal refcount by one" def Release(self): "Decrease the internal refcount by one" ! ! _methods_ = [ ! STDMETHOD(HRESULT, "QueryInterface", ! [POINTER(GUID), POINTER(_pbase)]), ! STDMETHOD(c_ulong, "AddRef"), ! STDMETHOD(c_ulong, "Release") ! ] __all__ = "IUnknown GUID HRESULT BSTR STDMETHOD".split() if __name__ == "__main__": ! help(POINTER(IUnknown)) --- 74,131 ---- def STDMETHOD(restype, name, argtypes=()): ! "Specifies a COM method slot" return restype, name, argtypes ! class _com_interface(object): __metaclass__ = _cominterface_meta + + class IUnknown(_com_interface): _iid_ = GUID("{00000000-0000-0000-C000-000000000046}") + _methods_ = [ + STDMETHOD(HRESULT, "QueryInterface", + [POINTER(GUID), POINTER(c_void_p)]), + STDMETHOD(c_ulong, "AddRef"), + STDMETHOD(c_ulong, "Release") + ] + def QueryInterface(self, interface): "QueryInterface(klass) -> instance" p = POINTER(interface)() ! self.__com_QueryInterface(byref(interface._iid_), byref(p)) return p def AddRef(self): "Increase the internal refcount by one" + return self.__com_AddRef() def Release(self): "Decrease the internal refcount by one" ! return self.__com_Release() __all__ = "IUnknown GUID HRESULT BSTR STDMETHOD".split() if __name__ == "__main__": ! POINTER(IUnknown)() ! ! p = POINTER(IUnknown)() ! ! ## assert bool(p) is True ! ## assert bool(p) is False ! ! windll.oleaut32.CreateTypeLib(1, u"blabla", byref(p)) ! assert (2, 1) == (p.AddRef(), p.Release()) ! ! p1 = p.QueryInterface(IUnknown) ! assert (3, 2) == (p1.AddRef(), p1.Release()) ! p2 = p1.QueryInterface(IUnknown) ! ! assert p1 == p2 ! ! del p2 ! del p ! assert (2, 1) == (p1.AddRef(), p1.Release()) ! ! ## help(POINTER(IUnknown)) ! ! del p1 |