def ParseRecord(self, tinfo, ta): members = [] # will be filled later struct_name, doc, helpcntext, helpfile = tinfo.GetDocumentation(-1) struct = typedesc.Structure(struct_name, align=ta.cbAlignment * 8, members=members, bases=[], size=ta.cbSizeInstance * 8) self._register(struct_name, struct) if ta.guid: tlib, _ = tinfo.GetContainingTypeLib() tlib_ta = tlib.GetLibAttr() struct._recordinfo_ = (str(tlib_ta.guid), tlib_ta.wMajorVerNum, tlib_ta.wMinorVerNum, tlib_ta.lcid, str(ta.guid)) for i in range(ta.cVars): vd = tinfo.GetVarDesc(i) name = tinfo.GetDocumentation(vd.memid)[0] offset = vd._.oInst * 8 assert vd.varkind == typeinfo.VAR_PERINSTANCE typ = self.make_type(vd.elemdescVar.tdesc, tinfo) field = typedesc.Field( name, typ, None, # bits offset) members.append(field) return struct
def make_type(self, tdesc, tinfo): try: return COMTYPES[tdesc.vt] except KeyError: pass if tdesc.vt == automation.VT_CARRAY: typ = self.make_type(tdesc._.lpadesc[0].tdescElem, tinfo) for i in range(tdesc._.lpadesc[0].cDims): typ = typedesc.ArrayType( typ, tdesc._.lpadesc[0].rgbounds[i].lLbound, tdesc._.lpadesc[0].rgbounds[i].cElements - 1) return typ elif tdesc.vt == automation.VT_PTR: typ = self.make_type(tdesc._.lptdesc[0], tinfo) return PTR(typ) elif tdesc.vt == automation.VT_USERDEFINED: try: ti = tinfo.GetRefTypeInfo(tdesc._.hreftype) except COMError as details: type_name = "__error_hreftype_%d__" % tdesc._.hreftype tlib_name = get_tlib_filename(self.tlib) if tlib_name is None: tlib_name = "unknown typelib" message = "\n\tGetRefTypeInfo failed in %s: %s\n\tgenerating type '%s' instead" % \ (tlib_name, details, type_name) import warnings warnings.warn(message, UserWarning) result = typedesc.Structure(type_name, align=8, members=[], bases=[], size=0) return result result = self.parse_typeinfo(ti) assert result is not None, ti.GetDocumentation(-1)[0] return result elif tdesc.vt == automation.VT_SAFEARRAY: # SAFEARRAY(<type>), see Don Box pp.331f itemtype = self.make_type(tdesc._.lptdesc[0], tinfo) return midlSAFEARRAY(itemtype) raise NotImplementedError(tdesc.vt)
def ParseRecord(self, tinfo, ta): members = [] # will be filled later struct_name, doc, helpcntext, helpfile = tinfo.GetDocumentation(-1) struct = typedesc.Structure(struct_name, align=ta.cbAlignment*8, members=members, bases=[], size=ta.cbSizeInstance*8) self._register(struct_name, struct) tlib, _ = tinfo.GetContainingTypeLib() tlib_ta = tlib.GetLibAttr() # If this is a 32-bit typlib being loaded in a 64-bit process, then the # size and alignment are incorrect. Set the size to None to disable # size checks and correct the alignment. if is_64bits and tlib_ta.syskind == typeinfo.SYS_WIN32: struct.size = None struct.align = 64 if ta.guid: struct._recordinfo_ = (str(tlib_ta.guid), tlib_ta.wMajorVerNum, tlib_ta.wMinorVerNum, tlib_ta.lcid, str(ta.guid)) for i in range(ta.cVars): vd = tinfo.GetVarDesc(i) name = tinfo.GetDocumentation(vd.memid)[0] offset = vd._.oInst * 8 assert vd.varkind == typeinfo.VAR_PERINSTANCE typ = self.make_type(vd.elemdescVar.tdesc, tinfo) field = typedesc.Field(name, typ, None, # bits offset) members.append(field) return struct
def make_type(self, tdesc, tinfo): try: return COMTYPES[tdesc.vt] except KeyError: pass if tdesc.vt == automation.VT_CARRAY: typ = self.make_type(tdesc._.lpadesc[0].tdescElem, tinfo) for i in range(tdesc._.lpadesc[0].cDims): typ = typedesc.ArrayType( typ, tdesc._.lpadesc[0].rgbounds[i].lLbound, tdesc._.lpadesc[0].rgbounds[i].cElements - 1) return typ elif tdesc.vt == automation.VT_PTR: typ = self.make_type(tdesc._.lptdesc[0], tinfo) return PTR(typ) elif tdesc.vt == automation.VT_USERDEFINED: try: ti = tinfo.GetRefTypeInfo(tdesc._.hreftype) except COMError, details: type_name = "__error_hreftype_%d__" % tdesc._.hreftype message = "\n\tGetRefTypeInfo failed: %s\n\tgenerating type '%s' instead" % \ (details, type_name) import warnings warnings.warn(message, UserWarning) result = typedesc.Structure(type_name, align=8, members=[], bases=[], size=0) return result result = self.parse_typeinfo(ti) assert result is not None, ti.GetDocumentation(-1)[0] return result
uint_type = typedesc.FundamentalType("unsigned int", 32, 32) long_type = typedesc.FundamentalType("long int", 32, 32) ulong_type = typedesc.FundamentalType("long unsigned int", 32, 32) longlong_type = typedesc.FundamentalType("long long int", 64, 64) ulonglong_type = typedesc.FundamentalType("long long unsigned int", 64, 64) float_type = typedesc.FundamentalType("float", 32, 32) double_type = typedesc.FundamentalType("double", 64, 64) # basic COM data types BSTR_type = typedesc.Typedef("BSTR", PTR(wchar_t_type)) SCODE_type = typedesc.Typedef("SCODE", int_type) VARIANT_BOOL_type = typedesc.Typedef("VARIANT_BOOL", short_type) HRESULT_type = typedesc.Typedef("HRESULT", ulong_type) VARIANT_type = typedesc.Structure("VARIANT", align=alignment(automation.VARIANT)*8, members=[], bases=[], size=sizeof(automation.VARIANT)*8) IDISPATCH_type = typedesc.Typedef("IDispatch", None) IUNKNOWN_type = typedesc.Typedef("IUnknown", None) DECIMAL_type = typedesc.Structure("DECIMAL", align=alignment(automation.DECIMAL)*8, members=[], bases=[], size=sizeof(automation.DECIMAL)*8) def midlSAFEARRAY(typ): return typedesc.SAFEARRAYType(typ) # faked COM data types CURRENCY_type = longlong_type # slightly wrong; should be scaled by 10000 - use subclass of longlong? DATE_type = double_type # not *that* wrong...