public static MethodImportAttributes MakeFlags(CallingConvention callingConvention) { MethodImportAttributes result = 0; switch (callingConvention) { default: // Dev10: uses default without reporting an error result |= MethodImportAttributes.CallingConventionStdCall; break; case CallingConvention.C: result |= MethodImportAttributes.CallingConventionCDecl; break; case CallingConvention.Standard: result |= MethodImportAttributes.CallingConventionStdCall; break; case CallingConvention.ThisCall: result |= MethodImportAttributes.CallingConventionThisCall; break; case CallingConvention.FastCall: result |= MethodImportAttributes.CallingConventionFastCall; break; } return(result); }
// used by DllImportAttribute public void SetDllImport(int attributeIndex, string moduleName, string entryPointName, MethodImportAttributes flags, bool preserveSig) { VerifySealed(expected: false); Debug.Assert(attributeIndex >= 0); _platformInvokeInfo = new DllImportData(moduleName, entryPointName, flags); _dllImportIndex = attributeIndex; _dllImportPreserveSig = preserveSig; SetDataStored(); }
internal DllImportData( string?moduleName, string?entryPointName, MethodImportAttributes flags ) { _moduleName = moduleName; _entryPointName = entryPointName; _flags = flags; }
private MethodImportAttributes GetImportAttributesFromBestFitMappingAttribute(CustomAttributeHandleCollection attributeHandles) { // Look for the [BestFitMapping(BestFitMapping: x, ThrowOnUnmappableChar = y)] attribute and // translate that to MethodImportAttributes MethodImportAttributes result = 0; MetadataReader reader = MetadataReader; CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle( attributeHandles, "System.Runtime.InteropServices", "BestFitMappingAttribute"); if (!attributeHandle.IsNil) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decoded = attribute.DecodeValue( new CustomAttributeTypeProvider(_type.EcmaModule)); if (decoded.FixedArguments.Length != 1 || !(decoded.FixedArguments[0].Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)decoded.FixedArguments[0].Value) { result |= MethodImportAttributes.BestFitMappingEnable; } else { result |= MethodImportAttributes.BestFitMappingDisable; } foreach (CustomAttributeNamedArgument <TypeDesc> namedArg in decoded.NamedArguments) { if (namedArg.Name == "ThrowOnUnmappableChar") { if (!(namedArg.Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)namedArg.Value) { result |= MethodImportAttributes.ThrowOnUnmappableCharEnable; } else { result |= MethodImportAttributes.ThrowOnUnmappableCharDisable; } break; } } } return(result); }
public void SetDllImport( int attributeIndex, string moduleName, string entryPointName, MethodImportAttributes flags, bool preserveSig ) { VerifySealed(expected: false); Debug.Assert(attributeIndex >= 0); _platformInvokeInfo = new DllImportData(moduleName, entryPointName, flags); _dllImportIndex = attributeIndex; _dllImportPreserveSig = preserveSig; SetDataStored(); }
public DecodedMethodImportAttributes(MethodImportAttributes attrs) { this.exact_spelling = (attrs & MethodImportAttributes.ExactSpelling) != 0; { MethodImportAttributes char_set_attr = attrs & MethodImportAttributes.CharSetMask; this.char_set = char_set_attr switch { MethodImportAttributes.None => CharSet.none, MethodImportAttributes.CharSetAnsi => CharSet.ansi, MethodImportAttributes.CharSetUnicode => CharSet.unicode, MethodImportAttributes.CharSetAuto => CharSet.auto, _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes char_set {0}", char_set_attr)), }; } { MethodImportAttributes best_fit_attr = attrs & MethodImportAttributes.BestFitMappingMask; this.best_fit = best_fit_attr switch { MethodImportAttributes.None => null, MethodImportAttributes.BestFitMappingDisable => false, MethodImportAttributes.BestFitMappingEnable => true, _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes best_fit {0}", best_fit_attr)), }; } this.set_last_error = (attrs & MethodImportAttributes.SetLastError) != 0; { MethodImportAttributes call_conv_attr = attrs & MethodImportAttributes.CallingConventionMask; this.call_conv = call_conv_attr switch { MethodImportAttributes.CallingConventionWinApi => CallConv.winapi, MethodImportAttributes.CallingConventionCDecl => CallConv.cdecl, MethodImportAttributes.CallingConventionStdCall => CallConv.stdcall, MethodImportAttributes.CallingConventionThisCall => CallConv.thiscall, MethodImportAttributes.CallingConventionFastCall => CallConv.fastcall, _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes call_conv {0}", call_conv_attr)), }; } { MethodImportAttributes throw_attr = attrs & MethodImportAttributes.ThrowOnUnmappableCharMask; this.throw_on_unmappable_char = throw_attr switch { MethodImportAttributes.None => null, MethodImportAttributes.ThrowOnUnmappableCharDisable => false, MethodImportAttributes.ThrowOnUnmappableCharEnable => true, _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes throw_on_unmappable {0}", throw_attr)), }; } }
private void ProcessPInvokeMapData( MethodInfo method, out string libraryName, out string entryName, out MethodImportAttributes implAttr) { CustomAttributeData dllImportData = null; foreach (var custAttr in method.GetCustomAttributesData()) { if (custAttr.AttributeType == typeof(DllImportAttribute)) { dllImportData = custAttr; break; } } if (dllImportData == null) { throw new InvalidProgramException($"Missing P/Invoke map data for: {method.Name}"); } // Initialize the outputs libraryName = (string)dllImportData.ConstructorArguments[0].Value; entryName = method.Name; implAttr = MethodImportAttributes.CallingConventionWinApi; foreach (var nargs in dllImportData.NamedArguments) { object argValue = nargs.TypedValue.Value; switch (nargs.MemberName) { case nameof(DllImportAttribute.BestFitMapping): implAttr |= ((bool)argValue) ? MethodImportAttributes.BestFitMappingEnable : MethodImportAttributes.BestFitMappingDisable; break; case nameof(DllImportAttribute.CallingConvention): // Clear previous value. implAttr &= ~MethodImportAttributes.CallingConventionMask; implAttr |= (CallingConvention)argValue switch { CallingConvention.Winapi => MethodImportAttributes.CallingConventionWinApi, CallingConvention.Cdecl => MethodImportAttributes.CallingConventionCDecl, CallingConvention.StdCall => MethodImportAttributes.CallingConventionStdCall, CallingConvention.ThisCall => MethodImportAttributes.CallingConventionThisCall, CallingConvention.FastCall => MethodImportAttributes.CallingConventionFastCall, _ => MethodImportAttributes.CallingConventionWinApi, }; break; case nameof(DllImportAttribute.CharSet): // Clear previous value. implAttr &= ~MethodImportAttributes.CharSetMask; implAttr |= (CharSet)argValue switch { CharSet.Ansi => MethodImportAttributes.CharSetAnsi, CharSet.Unicode => MethodImportAttributes.CharSetUnicode, CharSet.Auto => MethodImportAttributes.CharSetAuto, _ => MethodImportAttributes.None, }; break; case nameof(DllImportAttribute.EntryPoint): entryName = (string)argValue; break; case nameof(DllImportAttribute.ExactSpelling): implAttr |= ((bool)argValue) ? MethodImportAttributes.ExactSpelling : MethodImportAttributes.None; break; case nameof(DllImportAttribute.SetLastError): implAttr |= ((bool)argValue) ? MethodImportAttributes.SetLastError : MethodImportAttributes.None; break; case nameof(DllImportAttribute.ThrowOnUnmappableChar): implAttr |= ((bool)argValue) ? MethodImportAttributes.ThrowOnUnmappableCharEnable : MethodImportAttributes.ThrowOnUnmappableCharDisable; break; } } }
internal static MethodImportAttributes MakeFlags(bool exactSpelling, CharSet charSet, bool setLastError, CallingConvention callingConvention, bool?useBestFit, bool?throwOnUnmappable) { MethodImportAttributes result = 0; if (exactSpelling) { result |= MethodImportAttributes.ExactSpelling; } switch (charSet) { case CharSet.Ansi: result |= MethodImportAttributes.CharSetAnsi; break; case CharSet.Unicode: result |= MethodImportAttributes.CharSetUnicode; break; case Cci.Constants.CharSet_Auto: result |= MethodImportAttributes.CharSetAuto; break; // Dev10: use default without reporting an error } if (setLastError) { result |= MethodImportAttributes.SetLastError; } switch (callingConvention) { default: // Dev10: uses default without reporting an error result |= MethodImportAttributes.CallingConventionWinApi; break; case CallingConvention.Cdecl: result |= MethodImportAttributes.CallingConventionCDecl; break; case CallingConvention.StdCall: result |= MethodImportAttributes.CallingConventionStdCall; break; case CallingConvention.ThisCall: result |= MethodImportAttributes.CallingConventionThisCall; break; case Cci.Constants.CallingConvention_FastCall: result |= MethodImportAttributes.CallingConventionFastCall; break; } if (throwOnUnmappable.HasValue) { if (throwOnUnmappable.Value) { result |= MethodImportAttributes.ThrowOnUnmappableCharEnable; } else { result |= MethodImportAttributes.ThrowOnUnmappableCharDisable; } } if (useBestFit.HasValue) { if (useBestFit.Value) { result |= MethodImportAttributes.BestFitMappingEnable; } else { result |= MethodImportAttributes.BestFitMappingDisable; } } return(result); }
public void AddMethodImport( EntityHandle member, MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module) { _implMapTable.Add(new ImplMapRow { MemberForwarded = (uint)CodedIndex.ToMemberForwarded(member), ImportName = name, ImportScope = (uint)MetadataTokens.GetRowNumber(module), MappingFlags = (ushort)attributes, }); }
internal MethodImport(MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module) { _attributes = attributes; _name = name; _module = module; }
public DllImportData(string moduleName, string entryPointName, MethodImportAttributes flags) { _moduleName = moduleName; _entryPointName = entryPointName; _flags = flags; }
internal MethodImport(MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module) { this.attributes = attributes; this.name = name; this.module = module; }
public void AddMethodImport( uint member, MethodImportAttributes attributes, StringIdx name, int moduleReferenceRowId) { _implMapTable.Add(new ImplMapRow { MemberForwarded = member, ImportName = name, ImportScope = (uint)moduleReferenceRowId, MappingFlags = (ushort)attributes, }); }
internal DllImportData(string moduleName, string entryPointName, MethodImportAttributes flags) { _moduleName = moduleName; _entryPointName = entryPointName; _flags = flags; }
public override PInvokeMetadata GetPInvokeMethodMetadata() { if (!IsPInvoke) { return(default(PInvokeMetadata)); } MetadataReader metadataReader = MetadataReader; MethodDefinition methodDef = metadataReader.GetMethodDefinition(_handle); MethodImport import = methodDef.GetImport(); string name = metadataReader.GetString(import.Name); ModuleReference moduleRef = metadataReader.GetModuleReference(import.Module); string moduleName = metadataReader.GetString(moduleRef.Name); MethodImportAttributes importAttributes = import.Attributes; // If either BestFitMapping or ThrowOnUnmappable wasn't set on the p/invoke, // look for the value in the owning type or assembly. if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 || (importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0) { TypeDefinition declaringType = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType()); // Start with owning type MethodImportAttributes fromCA = GetImportAttributesFromBestFitMappingAttribute(declaringType.GetCustomAttributes()); if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0) { importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask; } if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0) { importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask; } // If we still don't know, check the assembly if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 || (importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0) { fromCA = GetImportAttributesFromBestFitMappingAttribute(metadataReader.GetAssemblyDefinition().GetCustomAttributes()); if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0) { importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask; } if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0) { importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask; } } } // Spot check the enums match Debug.Assert((int)MethodImportAttributes.CallingConventionStdCall == (int)PInvokeAttributes.CallingConventionStdCall); Debug.Assert((int)MethodImportAttributes.CharSetAuto == (int)PInvokeAttributes.CharSetAuto); Debug.Assert((int)MethodImportAttributes.CharSetUnicode == (int)PInvokeAttributes.CharSetUnicode); Debug.Assert((int)MethodImportAttributes.SetLastError == (int)PInvokeAttributes.SetLastError); PInvokeAttributes attributes = (PInvokeAttributes)importAttributes; if ((ImplAttributes & MethodImplAttributes.PreserveSig) != 0) { attributes |= PInvokeAttributes.PreserveSig; } return(new PInvokeMetadata(moduleName, name, attributes)); }