public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { string attrname = customBuilder.Ctor.ReflectedType.FullName; if (attrname == "System.Runtime.InteropServices.InAttribute") { attrs |= ParameterAttributes.In; return; } else if (attrname == "System.Runtime.InteropServices.OutAttribute") { attrs |= ParameterAttributes.Out; return; } else if (attrname == "System.Runtime.InteropServices.OptionalAttribute") { attrs |= ParameterAttributes.Optional; return; } else if (attrname == "System.Runtime.InteropServices.MarshalAsAttribute") { attrs |= ParameterAttributes.HasFieldMarshal; marshal_info = CustomAttributeBuilder.get_umarshal(customBuilder, false); /* FIXME: check for errors */ return; } else if (attrname == "System.Runtime.InteropServices.DefaultParameterValueAttribute") { /* MS.NET doesn't handle this attribute but we handle it for consistency */ CustomAttributeBuilder.CustomAttributeInfo cinfo = CustomAttributeBuilder.decode_cattr(customBuilder); /* FIXME: check for type compatibility */ SetConstant(cinfo.ctorArgs [0]); return; } if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1]; cattrs.CopyTo(new_array, 0); new_array [cattrs.Length] = customBuilder; cattrs = new_array; } else { cattrs = new CustomAttributeBuilder [1]; cattrs [0] = customBuilder; } }
public void SetCustomAttribute(CustomAttributeBuilder customBuilder) { if (customBuilder == null) { throw new ArgumentNullException("customBuilder"); } switch (customBuilder.Ctor.ReflectedType.FullName) { case "System.Runtime.CompilerServices.MethodImplAttribute": byte[] data = customBuilder.Data; int impla; // the (stupid) ctor takes a short or an int ... impla = (int)data [2]; impla |= ((int)data [3]) << 8; iattrs |= (MethodImplAttributes)impla; return; case "System.Runtime.InteropServices.DllImportAttribute": CustomAttributeBuilder.CustomAttributeInfo attr = CustomAttributeBuilder.decode_cattr(customBuilder); bool preserveSig = true; /* * It would be easier to construct a DllImportAttribute from * the custom attribute builder, but the DllImportAttribute * does not contain all the information required here, ie. * - some parameters, like BestFitMapping has three values * ("on", "off", "missing"), but DllImportAttribute only * contains two (on/off). * - PreserveSig is true by default, while it is false by * default in DllImportAttribute. */ pi_dll = (string)attr.ctorArgs[0]; if (pi_dll == null || pi_dll.Length == 0) { throw new ArgumentException("DllName cannot be empty"); } native_cc = System.Runtime.InteropServices.CallingConvention.Winapi; for (int i = 0; i < attr.namedParamNames.Length; ++i) { string name = attr.namedParamNames [i]; object value = attr.namedParamValues [i]; if (name == "CallingConvention") { native_cc = (CallingConvention)value; } else if (name == "CharSet") { charset = (CharSet)value; } else if (name == "EntryPoint") { pi_entry = (string)value; } else if (name == "ExactSpelling") { ExactSpelling = (bool)value; } else if (name == "SetLastError") { SetLastError = (bool)value; } else if (name == "PreserveSig") { preserveSig = (bool)value; } else if (name == "BestFitMapping") { BestFitMapping = (bool)value; } else if (name == "ThrowOnUnmappableChar") { ThrowOnUnmappableChar = (bool)value; } } attrs |= MethodAttributes.PinvokeImpl; if (preserveSig) { iattrs |= MethodImplAttributes.PreserveSig; } return; case "System.Runtime.InteropServices.PreserveSigAttribute": iattrs |= MethodImplAttributes.PreserveSig; return; case "System.Runtime.CompilerServices.SpecialNameAttribute": attrs |= MethodAttributes.SpecialName; return; case "System.Security.SuppressUnmanagedCodeSecurityAttribute": attrs |= MethodAttributes.HasSecurity; break; } if (cattrs != null) { CustomAttributeBuilder[] new_array = new CustomAttributeBuilder [cattrs.Length + 1]; cattrs.CopyTo(new_array, 0); new_array [cattrs.Length] = customBuilder; cattrs = new_array; } else { cattrs = new CustomAttributeBuilder [1]; cattrs [0] = customBuilder; } }
internal static CustomAttributeBuilder.CustomAttributeInfo decode_cattr(CustomAttributeBuilder customBuilder) { byte[] array = customBuilder.Data; ConstructorInfo constructorInfo = customBuilder.Ctor; int num = 0; CustomAttributeBuilder.CustomAttributeInfo result = default(CustomAttributeBuilder.CustomAttributeInfo); if (array.Length < 2) { throw new Exception("Custom attr length is only '" + array.Length + "'"); } if (array[0] != 1 || array[1] != 0) { throw new Exception("Prolog invalid"); } num = 2; ParameterInfo[] parameters = CustomAttributeBuilder.GetParameters(constructorInfo); result.ctor = constructorInfo; result.ctorArgs = new object[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { result.ctorArgs[i] = CustomAttributeBuilder.decode_cattr_value(parameters[i].ParameterType, array, num, out num); } int num2 = (int)array[num] + (int)array[num + 1] * 256; num += 2; result.namedParamNames = new string[num2]; result.namedParamValues = new object[num2]; for (int j = 0; j < num2; j++) { int num3 = (int)array[num++]; int num4 = (int)array[num++]; string text = null; if (num4 == 85) { int num5 = CustomAttributeBuilder.decode_len(array, num, out num); text = CustomAttributeBuilder.string_from_bytes(array, num, num5); num += num5; } int num6 = CustomAttributeBuilder.decode_len(array, num, out num); string text2 = CustomAttributeBuilder.string_from_bytes(array, num, num6); result.namedParamNames[j] = text2; num += num6; if (num3 != 83) { throw new Exception("Unknown named type: " + num3); } FieldInfo field = constructorInfo.DeclaringType.GetField(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field == null) { throw new Exception(string.Concat(new object[] { "Custom attribute type '", constructorInfo.DeclaringType, "' doesn't contain a field named '", text2, "'" })); } object obj = CustomAttributeBuilder.decode_cattr_value(field.FieldType, array, num, out num); if (text != null) { Type type = Type.GetType(text); obj = Enum.ToObject(type, obj); } result.namedParamValues[j] = obj; } return(result); }