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); }
/// <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; }
/// <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); }
/// <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)); }