コード例 #1
0
ファイル: ConvCommon2.cs プロジェクト: dbremner/clrinterop
        /// <summary>
        /// If the type is aliased, return the ultimated non-aliased type if the type is user-defined, otherwise, return
        /// the aliased type directly. So the result could still be aliased to a built-in type.
        /// If the type is not aliased, just return the type directly
        /// </summary>
        public static void ResolveAlias(TypeInfo type, TypeDesc typeDesc, out TypeInfo realType, out TypeAttr realAttr)
        {
            if (type == null) throw new ArgumentNullException(nameof(type));
            if (typeDesc == null) throw new ArgumentNullException(nameof(typeDesc));
            if ((VarEnum)typeDesc.vt != VarEnum.VT_USERDEFINED)
            {
                // Already resolved
                realType = type;
                realAttr = type.GetTypeAttr();
                return;
            }
            else
            {
                TypeInfo refType = type.GetRefTypeInfo(typeDesc.hreftype);
                TypeAttr refAttr = refType.GetTypeAttr();

                // If the userdefined typeinfo is not itself an alias, then it is what the alias aliases.
                // Also, if the userdefined typeinfo is an alias to a builtin type, then the builtin
                // type is what the alias aliases.
                if (refAttr.typekind != TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS || (VarEnum)refAttr.tdescAlias.vt != VarEnum.VT_USERDEFINED)
                {
                    // Resolved
                    realType = refType;
                    realAttr = refAttr;
                }
                else
                {
                    // Continue resolving the type
                    ResolveAlias(refType, refAttr.tdescAlias, out realType, out realAttr);
                }
            }
        }
コード例 #2
0
 public TypeInfo GetUserDefinedTypeInfo(TypeInfo typeinfo)
 {
     return(typeinfo.GetRefTypeInfo(hreftype));
 }
コード例 #3
0
ファイル: ConvUnion.cs プロジェクト: dbremner/clrinterop
        /// <summary>
        /// Test whether the typeDesc corresponds to a managed reference type
        /// </summary>
        private bool IsObjectType(TypeInfo typeInfo, TypeDesc typeDesc)
        {
            int nativeIndirection = 0;
            int vt = typeDesc.vt;

            // Strip off leading VT_PTR and VT_BYREF
            while (vt == (int)VarEnum.VT_PTR)
            {
                typeDesc = typeDesc.lptdesc;
                vt = typeDesc.vt;
                nativeIndirection++;
            }

            if ((vt & (int)VarEnum.VT_BYREF) != 0)
            {
                vt &= ~(int)VarEnum.VT_BYREF;
                nativeIndirection++;
            }

            // Determine if the field is/has object type.
            Debug.Assert(vt != (int)VarEnum.VT_PTR);

            switch ((VarEnum)vt)
            {
                // These are object types.
                case VarEnum.VT_BSTR:
                case VarEnum.VT_DISPATCH:
                case VarEnum.VT_VARIANT:
                case VarEnum.VT_UNKNOWN:
                case VarEnum.VT_SAFEARRAY:
                case VarEnum.VT_LPSTR:
                case VarEnum.VT_LPWSTR:
                    return true;

                // A user-defined may or may not be/contain Object type.
                case VarEnum.VT_USERDEFINED:
                    // User defined type.  Get the TypeInfo.
                    TypeInfo refTypeInfo = typeInfo.GetRefTypeInfo(typeDesc.hreftype);
                    TypeAttr refTypeAttr = refTypeInfo.GetTypeAttr();

                    // Some user defined class.  Is it a value class, or a VOS class?
                    switch (refTypeAttr.typekind)
                    {
                        // Alias -- Is the aliased thing an Object type?
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS:
                            return IsObjectType(refTypeInfo, refTypeAttr.tdescAlias);

                        // Record/Enum/Union -- Does it contain an Object type?
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_RECORD:
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_ENUM:
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_UNION:
                            // Byref/Ptrto record is Object.  Contained record might be.
                            if (nativeIndirection > 0)
                                return true;
                            else
                                return HasObjectFields(refTypeInfo);

                        // Class/Interface -- An Object Type.
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_INTERFACE:
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_DISPATCH:
                        case TypeLibTypes.Interop.TYPEKIND.TKIND_COCLASS:
                            return true;

                        default:
                            return true;

                    } // switch (psAttrAlias->typekind)

                case VarEnum.VT_CY:
                case VarEnum.VT_DATE:
                case VarEnum.VT_DECIMAL:
                    // Pointer to the value type is an object.  Contained one isn't.
                    if (nativeIndirection > 0)
                        return true;
                    else
                        return false;

                // A fixed array is an Object type.
                case VarEnum.VT_CARRAY:
                    return true;

                // Other types I4, etc., are not Object types.
                default:
                    return false;
            } // switch (vt=pType->vt)
        }
コード例 #4
0
ファイル: FuncDesc.cs プロジェクト: dbremner/clrinterop
 public TypeInfo GetUserDefinedTypeInfo(TypeInfo typeinfo)
 {
     if (typeinfo == null) throw new ArgumentNullException(nameof(typeinfo));
     return typeinfo.GetRefTypeInfo(hreftype);
 }
コード例 #5
0
ファイル: ConvCommon.cs プロジェクト: dbremner/clrinterop
        private static string GetAliasName(ConverterInfo info, TypeInfo typeInfo, TypeDesc typeDesc)
        {
            // Drill down to the actual type that is pointed to.
            while (typeDesc.vt == (int)VarEnum.VT_PTR)
                typeDesc = typeDesc.lptdesc;

            // If the parameter is an alias then we need to add a custom attribute to the
            // parameter that describes the alias.
            if (typeDesc.vt == (int)VarEnum.VT_USERDEFINED)
            {
                TypeInfo refTypeInfo = typeInfo.GetRefTypeInfo(typeDesc.hreftype);
                using (TypeAttr refTypeAttr = refTypeInfo.GetTypeAttr())
                {
                    if (refTypeAttr.typekind == TypeLibTypes.Interop.TYPEKIND.TKIND_ALIAS)
                    {
                        return info.GetManagedName(refTypeInfo);
                    }
                }
            }

            return null;
        }
コード例 #6
0
ファイル: ConvCommon.cs プロジェクト: dbremner/clrinterop
        /// <summary>
        /// Is this function a NewEnum function with the right parameters and DISPID?
        /// </summary>
        public static bool IsNewEnumFunc(ConverterInfo info, TypeInfo typeInfo, FuncDesc func, int index)
        {
            //
            // Support GUID_DispIdOverride
            //
            int dispid = func.memid;
            GetOverrideDispId(info, typeInfo, index, InterfaceMemberType.Method, ref dispid, false);

            if (dispid == WellKnownDispId.DISPID_NEWENUM)
            {
                TypeDesc typeDesc = null;

                if (func.funckind == TypeLibTypes.Interop.FUNCKIND.FUNC_DISPATCH)
                {
                    if (func.IsPropertyGet || func.IsFunc)
                    {
                        if (func.cParams == 0)
                        {
                            typeDesc = func.elemdescFunc.tdesc;
                        }
                        else if (info.TransformDispRetVal && func.cParams == 1 && func.GetElemDesc(0).paramdesc.IsRetval)
                        {
                            typeDesc = func.GetElemDesc(0).tdesc.lptdesc;
                        }
                    }
                }
                else if (func.funckind == TypeLibTypes.Interop.FUNCKIND.FUNC_PUREVIRTUAL)
                {
                    if ((func.cParams == 1) &&
                       (func.IsPropertyGet || func.IsFunc) &&
                       (func.GetElemDesc(0).paramdesc.IsRetval) &&
                       (func.GetElemDesc(0).tdesc.vt == (int)VarEnum.VT_PTR))
                    {
                        typeDesc = func.GetElemDesc(0).tdesc.lptdesc;
                    }
                }

                if (typeDesc != null)
                {
                    if (typeDesc.vt == (int)VarEnum.VT_UNKNOWN || typeDesc.vt == (int)VarEnum.VT_DISPATCH)
                    {
                        // The member returns an IUnknown* or an IDispatch* which is valid.
                        return true;
                    }
                    else if (typeDesc.vt == (int)VarEnum.VT_PTR)
                    {
                        typeDesc = typeDesc.lptdesc;
                        if (typeDesc.vt == (int)VarEnum.VT_USERDEFINED)
                        {
                            TypeInfo type = typeInfo.GetRefTypeInfo(typeDesc.hreftype);
                            using (TypeAttr attr = type.GetTypeAttr())
                            {
                                if (attr.Guid == WellKnownGuids.IID_IUnknown ||
                                   attr.Guid == WellKnownGuids.IID_IDispatch ||
                                   attr.Guid == WellKnownGuids.IID_IEnumVARIANT)
                                {
                                    return true;
                                }
                            }
                        }
                    }
                }
            }

            return false;
        }
コード例 #7
0
ファイル: ConvCommon.cs プロジェクト: dbremner/clrinterop
        /// <summary>
        /// Is this dispatch property a NewEnum property with the right type and DISPID?
        /// </summary>
        public static bool IsNewEnumDispatchProperty(ConverterInfo info, TypeInfo typeInfo, VarDesc var, int index)
        {
            //
            // Support GUID_DispIdOverride
            //
            int dispid = var.memid;
            GetOverrideDispId(info, typeInfo, index, InterfaceMemberType.Variable, ref dispid, false);

            if (dispid == WellKnownDispId.DISPID_NEWENUM &&
                var.elemdescVar.paramdesc.IsRetval &&
                var.IsReadOnly
                )
            {
                TypeDesc typeDesc = var.elemdescVar.tdesc;

                if (typeDesc.vt == (int)VarEnum.VT_UNKNOWN || typeDesc.vt == (int)VarEnum.VT_DISPATCH)
                {
                    return true;
                }
                else if (typeDesc.vt == (int)VarEnum.VT_PTR)
                {
                    typeDesc = typeDesc.lptdesc;
                    if (typeDesc.vt == (int)VarEnum.VT_USERDEFINED)
                    {
                        TypeInfo type = typeInfo.GetRefTypeInfo(typeDesc.hreftype);
                        using (TypeAttr attr = type.GetTypeAttr())
                        {
                            if (attr.Guid == WellKnownGuids.IID_IUnknown ||
                               attr.Guid == WellKnownGuids.IID_IDispatch ||
                               attr.Guid == WellKnownGuids.IID_IEnumVARIANT)
                            {
                                return true;
                            }
                        }
                    }
                }
            }

            return false;
        }