Exemplo n.º 1
0
        public unsafe ParameterDesc(ELEMDESC elemdesc, string name, Func<uint, TypeDesc> typeFactory, VARFLAGS flags, bool hasValue, object value)
        {
            Name = EscapeParameterName(name);
            SpecialFlag = flags.HasFlag(VARFLAGS.VARFLAG_FREPLACEABLE);
            Hidden = flags.HasFlag(VARFLAGS.VARFLAG_FHIDDEN);
            In = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FIN);
            Out = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FOUT);
            Optional = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FOPT);
            RetVal = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FRETVAL);
            HasValue = hasValue;
            Value = value;

            this.typeFactory = typeFactory;

            TYPEDESC typedesc = elemdesc.tdesc;
            while ((typedesc.vt & VARENUM.VT_TYPEMASK) == VARENUM.VT_PTR)
            {
                if ((typedesc.vt & ~VARENUM.VT_TYPEMASK) != VARENUM.VT_EMPTY)
                    throw new Exception("Variant type " + typedesc.vt + " is not supported");

                IndirectionLevel++;
                typedesc = *typedesc.__union1.lptdesc;
            }

            List<int> arraySizes = new List<int>();
            if ((typedesc.vt & VARENUM.VT_TYPEMASK) == VARENUM.VT_CARRAY)
            {
                SAFEARRAYBOUND* boundsPtr = &typedesc.__union1.lpadesc->rgbounds;
                for (int i = 0; i < typedesc.__union1.lpadesc->cDims; i++)
                    arraySizes.Add((int)boundsPtr[i].cElements - boundsPtr[i].lBound);
                typedesc = typedesc.__union1.lpadesc->tdescElem;
            }
            ArraySizes = arraySizes.AsReadOnly();

            if ((typedesc.vt & ~VARENUM.VT_TYPEMASK) != VARENUM.VT_EMPTY)
                throw new Exception("Variant type " + typedesc.vt + " is not supported");

            if (elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FHASDEFAULT))
            {
                if (hasValue)
                    throw new Exception("Explicit value cannot be set if default value is present");
                if (elemdesc.__union1.paramdesc.pparamdescex == null)
                    throw new Exception("Value address is null");
                Value = Marshal.GetObjectForNativeVariant(new IntPtr(&elemdesc.__union1.paramdesc.pparamdescex->varDefaultValue));
                HasValue = true;
            }

            switch (typedesc.vt & VARENUM.VT_TYPEMASK)
            {
                case VARENUM.VT_VARIANT:
                    type = new TypeDesc("VARIANT", TypeKind.Struct);
                    break;
                case VARENUM.VT_SAFEARRAY:
                    type = new TypeDesc("SAFEARRAY", TypeKind.Struct);
                    break;
                case VARENUM.VT_USERDEFINED:
                    typeReference = typedesc.__union1.hreftype;
                    break;
                case VARENUM.VT_UNKNOWN:
                    type = new TypeDesc("IUnknown", TypeKind.Interface);
                    IndirectionLevel++;
                    break;
                case VARENUM.VT_DISPATCH:
                    type = new TypeDesc("IDispatch", TypeKind.Interface);
                    IndirectionLevel++;
                    break;
                case VARENUM.VT_ERROR:
                case VARENUM.VT_HRESULT:
                    type = new TypeDesc("HRESULT");
                    break;
                case VARENUM.VT_LPSTR:
                    type = new TypeDesc("sbyte");
                    IndirectionLevel++;
                    break;
                case VARENUM.VT_BSTR:
                case VARENUM.VT_LPWSTR:
                    type = new TypeDesc("char");
                    IndirectionLevel++;
                    break;
                case VARENUM.VT_NULL:
                    type = new TypeDesc("void");
                    break;
                case VARENUM.VT_BOOL:
                    type = new TypeDesc("bool");
                    break;
                case VARENUM.VT_I1:
                    type = new TypeDesc("sbyte");
                    break;
                case VARENUM.VT_I2:
                    type = new TypeDesc("short");
                    break;
                case VARENUM.VT_I4:
                case VARENUM.VT_INT:
                    type = new TypeDesc("int");
                    break;
                case VARENUM.VT_I8:
                case VARENUM.VT_FILETIME:
                case VARENUM.VT_CY:
                    type = new TypeDesc("long");
                    break;
                case VARENUM.VT_UI1:
                    type = new TypeDesc("byte");
                    break;
                case VARENUM.VT_UI2:
                    type = new TypeDesc("ushort");
                    break;
                case VARENUM.VT_UI4:
                case VARENUM.VT_UINT:
                    type = new TypeDesc("uint");
                    break;
                case VARENUM.VT_UI8:
                    type = new TypeDesc("ulong");
                    break;
                case VARENUM.VT_R4:
                    type = new TypeDesc("float");
                    break;
                case VARENUM.VT_R8:
                case VARENUM.VT_DATE:
                    type = new TypeDesc("double");
                    break;
                case VARENUM.VT_DECIMAL:
                    type = new TypeDesc("decimal");
                    break;
                case VARENUM.VT_VOID:
                    type = new TypeDesc("void");
                    break;
                case VARENUM.VT_INT_PTR:
                case VARENUM.VT_UINT_PTR:
                    type = new TypeDesc("void");
                    IndirectionLevel++;
                    break;
                default:
                    throw new Exception("Variant type " + typedesc.vt + " is not supported");
            }
        }
Exemplo n.º 2
0
        public unsafe ParameterDesc(ELEMDESC elemdesc, string name, Func <uint, TypeDesc> typeFactory, VARFLAGS flags, bool hasValue, object value)
        {
            Name        = EscapeParameterName(name);
            SpecialFlag = flags.HasFlag(VARFLAGS.VARFLAG_FREPLACEABLE);
            Hidden      = flags.HasFlag(VARFLAGS.VARFLAG_FHIDDEN);
            In          = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FIN);
            Out         = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FOUT);
            Optional    = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FOPT);
            RetVal      = elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FRETVAL);
            HasValue    = hasValue;
            Value       = value;

            this.typeFactory = typeFactory;

            TYPEDESC typedesc = elemdesc.tdesc;

            while ((typedesc.vt & VARENUM.VT_TYPEMASK) == VARENUM.VT_PTR)
            {
                if ((typedesc.vt & ~VARENUM.VT_TYPEMASK) != VARENUM.VT_EMPTY)
                {
                    throw new Exception("Variant type " + typedesc.vt + " is not supported");
                }

                IndirectionLevel++;
                typedesc = *typedesc.__union1.lptdesc;
            }

            List <int> arraySizes = new List <int>();

            if ((typedesc.vt & VARENUM.VT_TYPEMASK) == VARENUM.VT_CARRAY)
            {
                SAFEARRAYBOUND *boundsPtr = &typedesc.__union1.lpadesc->rgbounds;
                for (int i = 0; i < typedesc.__union1.lpadesc->cDims; i++)
                {
                    arraySizes.Add((int)boundsPtr[i].cElements - boundsPtr[i].lBound);
                }
                typedesc = typedesc.__union1.lpadesc->tdescElem;
            }
            ArraySizes = arraySizes.AsReadOnly();

            if ((typedesc.vt & ~VARENUM.VT_TYPEMASK) != VARENUM.VT_EMPTY)
            {
                throw new Exception("Variant type " + typedesc.vt + " is not supported");
            }

            if (elemdesc.__union1.paramdesc.wParamFlags.HasFlag(PARAMFLAGS.PARAMFLAG_FHASDEFAULT))
            {
                if (hasValue)
                {
                    throw new Exception("Explicit value cannot be set if default value is present");
                }
                if (elemdesc.__union1.paramdesc.pparamdescex == null)
                {
                    throw new Exception("Value address is null");
                }
                Value    = Marshal.GetObjectForNativeVariant(new IntPtr(&elemdesc.__union1.paramdesc.pparamdescex->varDefaultValue));
                HasValue = true;
            }

            switch (typedesc.vt & VARENUM.VT_TYPEMASK)
            {
            case VARENUM.VT_VARIANT:
                type = new TypeDesc("VARIANT", TypeKind.Struct);
                break;

            case VARENUM.VT_SAFEARRAY:
                type = new TypeDesc("SAFEARRAY", TypeKind.Struct);
                break;

            case VARENUM.VT_USERDEFINED:
                typeReference = typedesc.__union1.hreftype;
                break;

            case VARENUM.VT_UNKNOWN:
                type = new TypeDesc("IUnknown", TypeKind.Interface);
                IndirectionLevel++;
                break;

            case VARENUM.VT_DISPATCH:
                type = new TypeDesc("IDispatch", TypeKind.Interface);
                IndirectionLevel++;
                break;

            case VARENUM.VT_ERROR:
            case VARENUM.VT_HRESULT:
                type = new TypeDesc("HRESULT");
                break;

            case VARENUM.VT_LPSTR:
                type = new TypeDesc("sbyte");
                IndirectionLevel++;
                break;

            case VARENUM.VT_BSTR:
            case VARENUM.VT_LPWSTR:
                type = new TypeDesc("char");
                IndirectionLevel++;
                break;

            case VARENUM.VT_NULL:
                type = new TypeDesc("void");
                break;

            case VARENUM.VT_BOOL:
                type = new TypeDesc("bool");
                break;

            case VARENUM.VT_I1:
                type = new TypeDesc("sbyte");
                break;

            case VARENUM.VT_I2:
                type = new TypeDesc("short");
                break;

            case VARENUM.VT_I4:
            case VARENUM.VT_INT:
                type = new TypeDesc("int");
                break;

            case VARENUM.VT_I8:
            case VARENUM.VT_FILETIME:
            case VARENUM.VT_CY:
                type = new TypeDesc("long");
                break;

            case VARENUM.VT_UI1:
                type = new TypeDesc("byte");
                break;

            case VARENUM.VT_UI2:
                type = new TypeDesc("ushort");
                break;

            case VARENUM.VT_UI4:
            case VARENUM.VT_UINT:
                type = new TypeDesc("uint");
                break;

            case VARENUM.VT_UI8:
                type = new TypeDesc("ulong");
                break;

            case VARENUM.VT_R4:
                type = new TypeDesc("float");
                break;

            case VARENUM.VT_R8:
            case VARENUM.VT_DATE:
                type = new TypeDesc("double");
                break;

            case VARENUM.VT_DECIMAL:
                type = new TypeDesc("decimal");
                break;

            case VARENUM.VT_VOID:
                type = new TypeDesc("void");
                break;

            case VARENUM.VT_INT_PTR:
            case VARENUM.VT_UINT_PTR:
                type = new TypeDesc("void");
                IndirectionLevel++;
                break;

            default:
                throw new Exception("Variant type " + typedesc.vt + " is not supported");
            }
        }