コード例 #1
0
        internal void SetMarshalAsSafeArray(VarEnum?elementType, ITypeSymbol elementTypeSymbol)
        {
            Debug.Assert(elementType == null || elementType >= 0 && (int)elementType <= MaxMarshalInteger);

            this.marshalType             = UnmanagedType.SafeArray;
            this.marshalArrayElementType = (int)(elementType ?? InvalidVariantType);
            this.marshalTypeNameOrSymbol = elementTypeSymbol;
        }
コード例 #2
0
ファイル: MarshalSpec.cs プロジェクト: raj581/Marvin
        internal static CustomAttributeData GetMarshalAsAttribute(Module module, int token)
        {
            // TODO use binary search?
            for (int i = 0; i < module.FieldMarshal.records.Length; i++)
            {
                if (module.FieldMarshal.records[i].Parent == token)
                {
                    ByteReader    blob                        = module.GetBlob(module.FieldMarshal.records[i].NativeType);
                    UnmanagedType unmanagedType               = (UnmanagedType)blob.ReadCompressedInt();
                    UnmanagedType?arraySubType                = null;
                    short?        sizeParamIndex              = null;
                    int?          sizeConst                   = null;
                    VarEnum?      safeArraySubType            = null;
                    Type          safeArrayUserDefinedSubType = null;
                    int?          iidParameterIndex           = null;
                    string        marshalType                 = null;
                    string        marshalCookie               = null;
                    Type          marshalTypeRef              = null;
                    if (unmanagedType == UnmanagedType.LPArray)
                    {
                        arraySubType = (UnmanagedType)blob.ReadCompressedInt();
                        if (arraySubType == NATIVE_TYPE_MAX)
                        {
                            arraySubType = null;
                        }
                        if (blob.Length != 0)
                        {
                            sizeParamIndex = (short)blob.ReadCompressedInt();
                            if (blob.Length != 0)
                            {
                                sizeConst = blob.ReadCompressedInt();
                                if (blob.Length != 0 && blob.ReadCompressedInt() == 0)
                                {
                                    sizeParamIndex = null;
                                }
                            }
                        }
                    }
                    else if (unmanagedType == UnmanagedType.SafeArray)
                    {
                        if (blob.Length != 0)
                        {
                            safeArraySubType = (VarEnum)blob.ReadCompressedInt();
                            if (blob.Length != 0)
                            {
                                safeArrayUserDefinedSubType = ReadType(module, blob);
                            }
                        }
                    }
                    else if (unmanagedType == UnmanagedType.ByValArray)
                    {
                        sizeConst = blob.ReadCompressedInt();
                        if (blob.Length != 0)
                        {
                            arraySubType = (UnmanagedType)blob.ReadCompressedInt();
                        }
                    }
                    else if (unmanagedType == UnmanagedType.ByValTStr)
                    {
                        sizeConst = blob.ReadCompressedInt();
                    }
                    else if (unmanagedType == UnmanagedType.Interface ||
                             unmanagedType == UnmanagedType.IDispatch ||
                             unmanagedType == UnmanagedType.IUnknown)
                    {
                        if (blob.Length != 0)
                        {
                            iidParameterIndex = blob.ReadCompressedInt();
                        }
                    }
                    else if (unmanagedType == UnmanagedType.CustomMarshaler)
                    {
                        blob.ReadCompressedInt();
                        blob.ReadCompressedInt();
                        marshalType   = ReadString(blob);
                        marshalCookie = ReadString(blob);

                        TypeNameParser parser = TypeNameParser.Parse(marshalType, false);
                        if (!parser.Error)
                        {
                            marshalTypeRef = parser.GetType(module.universe, module.Assembly, false, marshalType, false);
                        }
                    }

                    Type typeofMarshalAs     = module.universe.System_Runtime_InteropServices_MarshalAsAttribute;
                    Type typeofUnmanagedType = module.universe.System_Runtime_InteropServices_UnmanagedType;
                    Type typeofVarEnum       = module.universe.System_Runtime_InteropServices_VarEnum;
                    Type typeofType          = module.universe.System_Type;
                    List <CustomAttributeNamedArgument> named = new List <CustomAttributeNamedArgument>();
                    if (arraySubType != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "ArraySubType", typeofUnmanagedType, arraySubType.Value);
                    }
                    if (sizeParamIndex != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "SizeParamIndex", module.universe.System_Int16, sizeParamIndex.Value);
                    }
                    if (sizeConst != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "SizeConst", module.universe.System_Int32, sizeConst.Value);
                    }
                    if (safeArraySubType != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "SafeArraySubType", typeofVarEnum, safeArraySubType.Value);
                    }
                    if (safeArrayUserDefinedSubType != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "SafeArrayUserDefinedSubType", typeofType, safeArrayUserDefinedSubType);
                    }
                    if (iidParameterIndex != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "IidParameterIndex", module.universe.System_Int32, iidParameterIndex.Value);
                    }
                    if (marshalType != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "MarshalType", module.universe.System_String, marshalType);
                    }
                    if (marshalTypeRef != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "MarshalTypeRef", module.universe.System_Type, marshalTypeRef);
                    }
                    if (marshalCookie != null)
                    {
                        AddNamedArgument(named, typeofMarshalAs, "MarshalCookie", module.universe.System_String, marshalCookie);
                    }
                    ConstructorInfo constructor = typeofMarshalAs.GetPseudoCustomAttributeConstructor(typeofUnmanagedType);
                    return(new CustomAttributeData(module, constructor, new object[] { unmanagedType }, named));
                }
            }
            throw new BadImageFormatException();
        }
コード例 #3
0
        private static int WriteMarshallingDescriptor(ModuleBuilder module, CustomAttributeBuilder attribute)
        {
            UnmanagedType unmanagedType;
            object        val = attribute.GetConstructorArgument(0);

            if (val is short)
            {
                unmanagedType = (UnmanagedType)(short)val;
            }
            else if (val is int)
            {
                unmanagedType = (UnmanagedType)(int)val;
            }
            else
            {
                unmanagedType = (UnmanagedType)val;
            }

            ByteBuffer bb = new ByteBuffer(5);

            bb.WriteCompressedInt((int)unmanagedType);

            if (unmanagedType == UnmanagedType.LPArray)
            {
                UnmanagedType arraySubType = attribute.GetFieldValue <UnmanagedType>("ArraySubType") ?? NATIVE_TYPE_MAX;
                bb.WriteCompressedInt((int)arraySubType);
                int?sizeParamIndex = attribute.GetFieldValue <short>("SizeParamIndex");
                int?sizeConst      = attribute.GetFieldValue <int>("SizeConst");
                if (sizeParamIndex != null)
                {
                    bb.WriteCompressedInt(sizeParamIndex.Value);
                    if (sizeConst != null)
                    {
                        bb.WriteCompressedInt(sizeConst.Value);
                        bb.WriteCompressedInt(1);                         // flag that says that SizeParamIndex was specified
                    }
                }
                else if (sizeConst != null)
                {
                    bb.WriteCompressedInt(0);                     // SizeParamIndex
                    bb.WriteCompressedInt(sizeConst.Value);
                    bb.WriteCompressedInt(0);                     // flag that says that SizeParamIndex was not specified
                }
            }
            else if (unmanagedType == UnmanagedType.SafeArray)
            {
                VarEnum?safeArraySubType = attribute.GetFieldValue <VarEnum>("SafeArraySubType");
                if (safeArraySubType != null)
                {
                    bb.WriteCompressedInt((int)safeArraySubType);
                    Type safeArrayUserDefinedSubType = (Type)attribute.GetFieldValue("SafeArrayUserDefinedSubType");
                    if (safeArrayUserDefinedSubType != null)
                    {
                        WriteType(module, bb, safeArrayUserDefinedSubType);
                    }
                }
            }
            else if (unmanagedType == UnmanagedType.ByValArray)
            {
                bb.WriteCompressedInt(attribute.GetFieldValue <int>("SizeConst") ?? 1);
                UnmanagedType?arraySubType = attribute.GetFieldValue <UnmanagedType>("ArraySubType");
                if (arraySubType != null)
                {
                    bb.WriteCompressedInt((int)arraySubType);
                }
            }
            else if (unmanagedType == UnmanagedType.ByValTStr)
            {
                bb.WriteCompressedInt(attribute.GetFieldValue <int>("SizeConst").Value);
            }
            else if (unmanagedType == UnmanagedType.Interface ||
                     unmanagedType == UnmanagedType.IDispatch ||
                     unmanagedType == UnmanagedType.IUnknown)
            {
                int?iidParameterIndex = attribute.GetFieldValue <int>("IidParameterIndex");
                if (iidParameterIndex != null)
                {
                    bb.WriteCompressedInt(iidParameterIndex.Value);
                }
            }
            else if (unmanagedType == UnmanagedType.CustomMarshaler)
            {
                bb.WriteCompressedInt(0);
                bb.WriteCompressedInt(0);
                string marshalType = (string)attribute.GetFieldValue("MarshalType");
                if (marshalType != null)
                {
                    WriteString(bb, marshalType);
                }
                else
                {
                    WriteType(module, bb, (Type)attribute.GetFieldValue("MarshalTypeRef"));
                }
                WriteString(bb, (string)attribute.GetFieldValue("MarshalCookie") ?? "");
            }

            return(module.Blobs.Add(bb));
        }
コード例 #4
0
        private static void DecodeMarshalAsSafeArray(ref DecodeWellKnownAttributeArguments <TAttributeSyntax, TAttributeData, TAttributeLocation> arguments, CommonMessageProvider messageProvider)
        {
            Debug.Assert((object)arguments.AttributeSyntaxOpt != null);

            VarEnum?    elementTypeVariant = null;
            ITypeSymbol elementTypeSymbol  = null;
            int         symbolIndex        = -1;
            bool        hasErrors          = false;

            int position = 1;

            foreach (var namedArg in arguments.Attribute.NamedArguments)
            {
                switch (namedArg.Key)
                {
                case "SafeArraySubType":
                    elementTypeVariant = namedArg.Value.DecodeValue <VarEnum>(SpecialType.System_Enum);
                    if (elementTypeVariant < 0 || (int)elementTypeVariant > MarshalPseudoCustomAttributeData.MaxMarshalInteger)
                    {
                        messageProvider.ReportInvalidNamedArgument(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position, arguments.Attribute.AttributeClass, namedArg.Key);
                        hasErrors = true;
                    }

                    break;

                case "SafeArrayUserDefinedSubType":
                    elementTypeSymbol = namedArg.Value.DecodeValue <ITypeSymbol>(SpecialType.None);
                    symbolIndex       = position;
                    break;

                case "ArraySubType":
                case "SizeConst":
                case "SizeParamIndex":
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, position);
                    hasErrors = true;
                    break;

                    // other parameters ignored with no error
                }

                position++;
            }

            switch (elementTypeVariant)
            {
            case VarEnum.VT_DISPATCH:
            case VarEnum.VT_UNKNOWN:
            case VarEnum.VT_RECORD:
                // only these variants accept specification of user defined subtype
                break;

            default:
                if (elementTypeVariant != null && symbolIndex >= 0)
                {
                    messageProvider.ReportParameterNotValidForType(arguments.Diagnostics, arguments.AttributeSyntaxOpt, symbolIndex);
                    hasErrors = true;
                }
                else
                {
                    // type ignored:
                    elementTypeSymbol = null;
                }

                break;
            }

            if (!hasErrors)
            {
                arguments.GetOrCreateData <TWellKnownAttributeData>().GetOrCreateData().SetMarshalAsSafeArray(elementTypeVariant, elementTypeSymbol);
            }
        }