| File: Symbols\PlatformInvokeInformation.cs | Web Access |
| Project: src\roslyn\src\Compilers\Core\Portable\Microsoft.CodeAnalysis.csproj (Microsoft.CodeAnalysis) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Reflection; using System.Runtime.InteropServices; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis { /// <summary> /// Information that describes how a method from the underlying Platform is to be invoked. /// </summary> public sealed class DllImportData : Cci.IPlatformInvokeInformation { private readonly string? _moduleName; private readonly string? _entryPointName; // null if unspecified, the name of the target method should be used private readonly MethodImportAttributes _flags; internal DllImportData(string? moduleName, string? entryPointName, MethodImportAttributes flags) { _moduleName = moduleName; _entryPointName = entryPointName; _flags = flags; } /// <summary> /// Module name. Null if value specified in the attribute is not valid. /// </summary> public string? ModuleName { get { return _moduleName; } } /// <summary> /// Name of the native entry point or null if not specified (the effective name is the same as the name of the target method). /// </summary> public string? EntryPointName { get { return _entryPointName; } } MethodImportAttributes Cci.IPlatformInvokeInformation.Flags { get { return _flags; } } /// <summary> /// Controls whether the <see cref="CharacterSet"/> field causes the common language runtime /// to search an unmanaged DLL for entry-point names other than the one specified. /// </summary> public bool ExactSpelling { get { return (_flags & MethodImportAttributes.ExactSpelling) != 0; } } /// <summary> /// Indicates how to marshal string parameters and controls name mangling. /// </summary> public CharSet CharacterSet { get { switch (_flags & MethodImportAttributes.CharSetMask) { case MethodImportAttributes.CharSetAnsi: return CharSet.Ansi; case MethodImportAttributes.CharSetUnicode: return CharSet.Unicode; case MethodImportAttributes.CharSetAuto: return Cci.Constants.CharSet_Auto; case 0: return Cci.Constants.CharSet_None; } throw ExceptionUtilities.UnexpectedValue(_flags); } } /// <summary> /// Indicates whether the callee calls the SetLastError Win32 API function before returning from the attributed method. /// </summary> public bool SetLastError { get { return (_flags & MethodImportAttributes.SetLastError) != 0; } } /// <summary> /// Indicates the calling convention of an entry point. /// </summary> public CallingConvention CallingConvention { get { switch (_flags & MethodImportAttributes.CallingConventionMask) { default: return CallingConvention.Winapi; case MethodImportAttributes.CallingConventionCDecl: return CallingConvention.Cdecl; case MethodImportAttributes.CallingConventionStdCall: return CallingConvention.StdCall; case MethodImportAttributes.CallingConventionThisCall: return CallingConvention.ThisCall; case MethodImportAttributes.CallingConventionFastCall: return Cci.Constants.CallingConvention_FastCall; } } } /// <summary> /// Enables or disables best-fit mapping behavior when converting Unicode characters to ANSI characters. /// Null if not specified (the setting for the containing type or assembly should be used, <see cref="BestFitMappingAttribute"/>). /// </summary> public bool? BestFitMapping { get { switch (_flags & MethodImportAttributes.BestFitMappingMask) { case MethodImportAttributes.BestFitMappingEnable: return true; case MethodImportAttributes.BestFitMappingDisable: return false; default: return null; } } } /// <summary> /// Enables or disables the throwing of an exception on an unmappable Unicode character that is converted to an ANSI "?" character. /// Null if not specified. /// </summary> public bool? ThrowOnUnmappableCharacter { get { switch (_flags & MethodImportAttributes.ThrowOnUnmappableCharMask) { case MethodImportAttributes.ThrowOnUnmappableCharEnable: return true; case MethodImportAttributes.ThrowOnUnmappableCharDisable: return false; default: return null; } } } 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; } } }