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); }