Beispiel #1
0
        public static bool IsMarshallingRequired(MethodSignature methodSig, ParameterMetadata[] paramMetadata)
        {
            for (int i = 0, paramIndex = 0; i < methodSig.Length + 1; i++)
            {
                ParameterMetadata parameterMetadata = (paramIndex == paramMetadata.Length || i < paramMetadata[paramIndex].Index) ?
                                                      new ParameterMetadata(i, ParameterMetadataAttributes.None, null) :
                                                      paramMetadata[paramIndex++];

                TypeDesc parameterType = (i == 0) ? methodSig.ReturnType : methodSig[i - 1];  //first item is the return type

                MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
                    parameterType,
                    parameterMetadata.MarshalAsDescriptor,
                    parameterMetadata.Return,
                    isAnsi: true,
                    MarshallerType.Argument,
                    out MarshallerKind elementMarshallerKind);

                if (IsMarshallingRequired(marshallerKind))
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Returns true if this type has a common representation in both managed and unmanaged memory
        /// and does not require special handling by the interop marshaler.
        /// </summary>
        public static bool IsBlittableType(TypeDesc type)
        {
            if (!type.IsDefType)
            {
                return false;
            }

            TypeDesc baseType = type.BaseType;
            bool hasNonTrivialParent = baseType != null
                && !baseType.IsWellKnownType(WellKnownType.Object)
                && !baseType.IsWellKnownType(WellKnownType.ValueType);

            if (hasNonTrivialParent && !IsBlittableType(baseType))
            {
                return false;
            }

            var mdType = (MetadataType)type;

            if (!mdType.IsSequentialLayout && !mdType.IsExplicitLayout)
            {
                return false;
            }

            foreach (FieldDesc field in type.GetFields())
            {
                if (field.IsStatic)
                {
                    continue;
                }

#if READYTORUN
                if (!field.FieldType.IsValueType)
                {
                    // Types with fields of non-value types cannot be blittable
                    // This check prevents possible infinite recursion where GetMarshallerKind would call back to IsBlittable e.g. for
                    // the case of classes with pointer members to the class itself.
                    return false;
                }
#endif

                MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
                    field.FieldType,
                    field.GetMarshalAsDescriptor(),
                    isReturn: false,
                    isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass,
                    MarshallerType.Field,
                    elementMarshallerKind: out var _);

                if (marshallerKind != MarshallerKind.Enum
                    && marshallerKind != MarshallerKind.BlittableValue
                    && marshallerKind != MarshallerKind.BlittableStruct
                    && marshallerKind != MarshallerKind.UnicodeChar)
                {
                    return false;
                }
            }

            return true;
        }
Beispiel #3
0
        /// <summary>
        /// Returns true if this type has a common representation in both managed and unmanaged memory
        /// and does not require special handling by the interop marshaler.
        /// </summary>
        public static bool IsBlittableType(TypeDesc type)
        {
            if (!type.IsDefType)
            {
                return(false);
            }

            DefType baseType            = type.BaseType;
            bool    hasNonTrivialParent = baseType != null &&
                                          !baseType.IsWellKnownType(WellKnownType.Object) &&
                                          !baseType.IsWellKnownType(WellKnownType.ValueType);

            // Type is blittable only if parent is also blittable and is not empty.
            if (hasNonTrivialParent && (!IsBlittableType(baseType) || baseType.IsZeroSizedReferenceType))
            {
                return(false);
            }

            var mdType = (MetadataType)type;

            if (!mdType.IsSequentialLayout && !mdType.IsExplicitLayout)
            {
                return(false);
            }

            foreach (FieldDesc field in type.GetFields())
            {
                if (field.IsStatic)
                {
                    continue;
                }

                MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
                    field.FieldType,
                    parameterIndex: null,
                    customModifierData: null,
                    field.GetMarshalAsDescriptor(),
                    isReturn: false,
                    isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass,
                    MarshallerType.Field,
                    elementMarshallerKind: out var _);

                if (marshallerKind != MarshallerKind.Enum &&
                    marshallerKind != MarshallerKind.BlittableValue &&
                    marshallerKind != MarshallerKind.BlittableStruct &&
                    marshallerKind != MarshallerKind.UnicodeChar)
                {
                    return(false);
                }
            }

            return(true);
        }
Beispiel #4
0
        /// <summary>
        /// Returns true if this type has a common representation in both managed and unmanaged memory
        /// and does not require special handling by the interop marshaler.
        /// </summary>
        public static bool IsBlittableType(TypeDesc type)
        {
            if (!type.IsDefType)
            {
                return(false);
            }

            TypeDesc baseType            = type.BaseType;
            bool     hasNonTrivialParent = baseType != null &&
                                           !baseType.IsWellKnownType(WellKnownType.Object) &&
                                           !baseType.IsWellKnownType(WellKnownType.ValueType);

            if (hasNonTrivialParent && !IsBlittableType(baseType))
            {
                return(false);
            }

            var mdType = (MetadataType)type;

            if (!mdType.IsSequentialLayout && !mdType.IsExplicitLayout)
            {
                return(false);
            }

            foreach (FieldDesc field in type.GetFields())
            {
                if (field.IsStatic)
                {
                    continue;
                }

                MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(
                    field.FieldType,
                    field.GetMarshalAsDescriptor(),
                    isReturn: false,
                    isAnsi: mdType.PInvokeStringFormat == PInvokeStringFormat.AnsiClass,
                    MarshallerType.Field,
                    elementMarshallerKind: out var _);

                if (marshallerKind != MarshallerKind.Enum &&
                    marshallerKind != MarshallerKind.BlittableValue &&
                    marshallerKind != MarshallerKind.BlittableStruct &&
                    marshallerKind != MarshallerKind.UnicodeChar)
                {
                    return(false);
                }
            }

            return(true);
        }
        internal static TypeDesc GetNativeStructFieldType(TypeDesc type, MarshalAsDescriptor marshalAs, InteropStateManager interopStateManager, bool isAnsi)
        {
            MarshallerKind elementMarshallerKind;
            MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(type,
                                                                             marshalAs,
                                                                             false,  /*  isReturn */
                                                                             isAnsi, /*    isAnsi */
                                                                             MarshallerType.Field,
                                                                             out elementMarshallerKind);

            return(GetNativeTypeFromMarshallerKind(type,
                                                   marshallerKind,
                                                   elementMarshallerKind,
                                                   interopStateManager,
                                                   marshalAs));
        }
        internal static TypeDesc GetNativeMethodParameterType(TypeDesc type, MarshalAsDescriptor marshalAs, InteropStateManager interopStateManager, bool isReturn, bool isAnsi)
        {
            MarshallerKind elementMarshallerKind;
            MarshallerKind marshallerKind = MarshalHelpers.GetMarshallerKind(type,
                                                                             marshalAs,
                                                                             isReturn,
                                                                             isAnsi,
                                                                             MarshallerType.Argument,
                                                                             out elementMarshallerKind);

            return(GetNativeTypeFromMarshallerKind(type,
                                                   marshallerKind,
                                                   elementMarshallerKind,
                                                   interopStateManager,
                                                   marshalAs));
        }