Exemple #1
0
        internal static TypeDesc GetNativeTypeFromMarshallerKind(TypeDesc type,
                                                                 MarshallerKind kind,
                                                                 MarshallerKind elementMarshallerKind,
#if !READYTORUN
                                                                 InteropStateManager interopStateManager,
#endif
                                                                 MarshalAsDescriptor marshalAs,
                                                                 bool isArrayElement = false)
        {
            TypeSystemContext context    = type.Context;
            NativeTypeKind    nativeType = NativeTypeKind.Default;

            if (marshalAs != null)
            {
                nativeType = isArrayElement ? marshalAs.ArraySubType : marshalAs.Type;
            }

            switch (kind)
            {
            case MarshallerKind.BlittableValue:
            {
                switch (nativeType)
                {
                case NativeTypeKind.I1:
                    return(context.GetWellKnownType(WellKnownType.SByte));

                case NativeTypeKind.U1:
                    return(context.GetWellKnownType(WellKnownType.Byte));

                case NativeTypeKind.I2:
                    return(context.GetWellKnownType(WellKnownType.Int16));

                case NativeTypeKind.U2:
                    return(context.GetWellKnownType(WellKnownType.UInt16));

                case NativeTypeKind.I4:
                    return(context.GetWellKnownType(WellKnownType.Int32));

                case NativeTypeKind.U4:
                    return(context.GetWellKnownType(WellKnownType.UInt32));

                case NativeTypeKind.I8:
                    return(context.GetWellKnownType(WellKnownType.Int64));

                case NativeTypeKind.U8:
                    return(context.GetWellKnownType(WellKnownType.UInt64));

                case NativeTypeKind.R4:
                    return(context.GetWellKnownType(WellKnownType.Single));

                case NativeTypeKind.R8:
                    return(context.GetWellKnownType(WellKnownType.Double));

                default:
                    return(type.UnderlyingType);
                }
            }

            case MarshallerKind.Bool:
                return(context.GetWellKnownType(WellKnownType.Int32));

            case MarshallerKind.CBool:
                return(context.GetWellKnownType(WellKnownType.Byte));

            case MarshallerKind.VariantBool:
                return(context.GetWellKnownType(WellKnownType.Int16));

            case MarshallerKind.Enum:
            case MarshallerKind.BlittableStruct:
            case MarshallerKind.Decimal:
            case MarshallerKind.VoidReturn:
                return(type);

#if !READYTORUN
            case MarshallerKind.Struct:
            case MarshallerKind.LayoutClass:
                return(interopStateManager.GetStructMarshallingNativeType((MetadataType)type));
#endif

            case MarshallerKind.BlittableStructPtr:
                return(type.MakePointerType());

            case MarshallerKind.HandleRef:
                return(context.GetWellKnownType(WellKnownType.IntPtr));

            case MarshallerKind.UnicodeChar:
                if (nativeType == NativeTypeKind.U2)
                {
                    return(context.GetWellKnownType(WellKnownType.UInt16));
                }
                else
                {
                    return(context.GetWellKnownType(WellKnownType.Int16));
                }

            case MarshallerKind.OleDateTime:
                return(context.GetWellKnownType(WellKnownType.Double));

            case MarshallerKind.SafeHandle:
            case MarshallerKind.CriticalHandle:
                return(context.GetWellKnownType(WellKnownType.IntPtr));

            case MarshallerKind.BSTRString:
            case MarshallerKind.UnicodeString:
            case MarshallerKind.UnicodeStringBuilder:
                return(context.GetWellKnownType(WellKnownType.Char).MakePointerType());

            case MarshallerKind.AnsiBSTRString:
            case MarshallerKind.AnsiString:
            case MarshallerKind.AnsiStringBuilder:
            case MarshallerKind.UTF8String:
                return(context.GetWellKnownType(WellKnownType.Byte).MakePointerType());

            case MarshallerKind.BlittableArray:
            case MarshallerKind.Array:
            case MarshallerKind.AnsiCharArray:
            {
                ArrayType arrayType = type as ArrayType;
                Debug.Assert(arrayType != null, "Expecting array");

                //
                // We need to construct the unsafe array from the right unsafe array element type
                //
                TypeDesc elementNativeType = GetNativeTypeFromMarshallerKind(
                    arrayType.ElementType,
                    elementMarshallerKind,
                    MarshallerKind.Unknown,
#if !READYTORUN
                    interopStateManager,
#endif
                    marshalAs,
                    isArrayElement: true);

                return(elementNativeType.MakePointerType());
            }

            case MarshallerKind.AnsiChar:
                return(context.GetWellKnownType(WellKnownType.Byte));

            case MarshallerKind.FunctionPointer:
                return(context.GetWellKnownType(WellKnownType.IntPtr));

#if !READYTORUN
            case MarshallerKind.ByValUnicodeString:
            case MarshallerKind.ByValAnsiString:
            {
                var inlineArrayCandidate = GetInlineArrayCandidate(context.GetWellKnownType(WellKnownType.Char), elementMarshallerKind, interopStateManager, marshalAs);
                return(interopStateManager.GetInlineArrayType(inlineArrayCandidate));
            }

            case MarshallerKind.ByValAnsiCharArray:
            case MarshallerKind.ByValArray:
            {
                ArrayType arrayType = type as ArrayType;
                Debug.Assert(arrayType != null, "Expecting array");

                var inlineArrayCandidate = GetInlineArrayCandidate(arrayType.ElementType, elementMarshallerKind, interopStateManager, marshalAs);

                return(interopStateManager.GetInlineArrayType(inlineArrayCandidate));
            }
#endif

            case MarshallerKind.LayoutClassPtr:
            case MarshallerKind.AsAnyA:
            case MarshallerKind.AsAnyW:
                return(context.GetWellKnownType(WellKnownType.IntPtr));

            case MarshallerKind.ComInterface:
                return(context.GetWellKnownType(WellKnownType.IntPtr));

#if !READYTORUN
            case MarshallerKind.Variant:
                return(InteropTypes.GetVariant(context));
#endif

            case MarshallerKind.OleCurrency:
                return(context.GetWellKnownType(WellKnownType.Int64));

            case MarshallerKind.Unknown:
            default:
                throw new NotSupportedException();
            }
        }