Пример #1
0
        private CustomAttributeBuilder GetMarshalAsAttribute(Cci.IMarshallingInformation marshallingInformation)
        {
            if (s_marshalAsCtor == null)
            {
                Type m = typeof(MarshalAsAttribute);
                s_marshalAsCtor = m.GetConstructor(new[] { typeof(UnmanagedType) });
                s_marshalArraySubType = m.GetField("ArraySubType");
                s_marshalIidParameterIndex = m.GetField("IidParameterIndex");
                s_marshalMarshalCookie = m.GetField("MarshalCookie");
                s_marshalMarshalType = m.GetField("MarshalType");
                s_marshalMarshalTypeRef = m.GetField("MarshalTypeRef");
                s_marshalSafeArraySubType = m.GetField("SafeArraySubType");
                s_marshalSafeArrayUserDefinedSubType = m.GetField("SafeArrayUserDefinedSubType");
                s_marshalSizeConst = m.GetField("SizeConst");
                s_marshalSizeParamIndex = m.GetField("SizeParamIndex");
            }

            FieldInfo[] fields = SpecializedCollections.EmptyArray<FieldInfo>();
            object[] values = SpecializedCollections.EmptyArray<object>();

            switch (marshallingInformation.UnmanagedType)
            {
                case UnmanagedType.ByValArray:
                    Debug.Assert(marshallingInformation.NumberOfElements >= 0);
                    if (marshallingInformation.ElementType >= 0)
                    {
                        fields = new[] { s_marshalSizeConst, s_marshalArraySubType };
                        values = new object[] { marshallingInformation.NumberOfElements, marshallingInformation.ElementType };
                    }
                    else
                    {
                        fields = new[] { s_marshalSizeConst };
                        values = new object[] { marshallingInformation.NumberOfElements };
                    }

                    break;

                case UnmanagedType.CustomMarshaler:
                    var marshaller = marshallingInformation.GetCustomMarshaller(_context);
                    var marshallerTypeRef = marshaller as Cci.ITypeReference;
                    if (marshallerTypeRef != null)
                    {
                        Type resolvedMarshaller = ResolveType(marshallerTypeRef);

                        fields = new[] { s_marshalMarshalTypeRef, s_marshalMarshalCookie };
                        values = new object[] { resolvedMarshaller, marshallingInformation.CustomMarshallerRuntimeArgument };
                    }
                    else
                    {
                        fields = new[] { s_marshalMarshalType, s_marshalMarshalCookie };
                        values = new object[] { marshaller, marshallingInformation.CustomMarshallerRuntimeArgument };
                    }

                    break;

                case UnmanagedType.LPArray:
                    var valueBuilder = ArrayBuilder<object>.GetInstance();
                    var fieldBuilder = ArrayBuilder<FieldInfo>.GetInstance();

                    fieldBuilder.Add(s_marshalArraySubType);
                    valueBuilder.Add(marshallingInformation.ElementType);

                    if (marshallingInformation.ParamIndex >= 0)
                    {
                        fieldBuilder.Add(s_marshalSizeParamIndex);
                        valueBuilder.Add(marshallingInformation.ParamIndex);
                    }

                    if (marshallingInformation.NumberOfElements >= 0)
                    {
                        fieldBuilder.Add(s_marshalSizeConst);
                        valueBuilder.Add(marshallingInformation.NumberOfElements);
                    }

                    fields = fieldBuilder.ToArrayAndFree();
                    values = valueBuilder.ToArrayAndFree();
                    break;

                case UnmanagedType.SafeArray:
                    if (marshallingInformation.SafeArrayElementSubtype >= 0)
                    {
                        var elementType = marshallingInformation.GetSafeArrayElementUserDefinedSubtype(_context);
                        if (elementType != null)
                        {
                            var resolvedType = ResolveType(elementType);

                            fields = new[] { s_marshalSafeArraySubType, s_marshalSafeArrayUserDefinedSubType };
                            values = new object[] { marshallingInformation.SafeArrayElementSubtype, resolvedType };
                        }
                        else
                        {
                            fields = new[] { s_marshalSafeArraySubType };
                            values = new object[] { marshallingInformation.SafeArrayElementSubtype };
                        }
                    }

                    break;

                case UnmanagedType.ByValTStr:
                    Debug.Assert(marshallingInformation.NumberOfElements >= 0);
                    fields = new[] { s_marshalSizeConst };
                    values = new object[] { marshallingInformation.NumberOfElements };
                    break;

                case UnmanagedType.Interface:
                case UnmanagedType.IDispatch:
                case UnmanagedType.IUnknown:
                    if (marshallingInformation.IidParameterIndex >= 0)
                    {
                        fields = new[] { s_marshalIidParameterIndex };
                        values = new object[] { marshallingInformation.IidParameterIndex };
                    }

                    break;

                default:
                    break;
            }

            return new CustomAttributeBuilder(s_marshalAsCtor, new object[] { marshallingInformation.UnmanagedType }, fields, values);
        }