public TypeNameConfig(int nestingLevel, TypeNameConfig[] genericParamsConfig, ArrayKind arrayKind, bool assemblyQualified) { this.nestingLevel = nestingLevel; this.genericParamsConfig = genericParamsConfig; this.arrayKind = arrayKind; this.assemblyQualified = assemblyQualified; }
public TypeNameConfig(int nestingLevel, TypeNameConfig[] genericParamsConfig, int pointerCount, ArrayKind arrayKind, bool assemblyQualified) { this.NestingLevel = nestingLevel; this.GenericParamsConfig = genericParamsConfig; this.PointerCount = pointerCount; this.ArrayKind = arrayKind; this.AssemblyQualified = assemblyQualified; }
/// <summary> /// Initializes the array as a <see cref="UnmanagedType.SafeArray"/>. /// </summary> private void InitializeAsSafeArray(NativeTypeDesc desc) { this.arrayKind = ArrayKind.SafeArray; Type array_mng_type = desc.Type; VarEnum sub_type = VarEnum.VT_EMPTY; if (desc.MarshalAs != null && desc.MarshalAs.SafeArraySubType != VarEnum.VT_EMPTY) { sub_type = desc.MarshalAs.SafeArraySubType; } else { // the unmanaged type may also be specified statically using one of the wrapper classes if (array_mng_type == typeof(UnknownWrapper[])) { array_mng_type = typeof(object[]); sub_type = VarEnum.VT_UNKNOWN; } else if (array_mng_type == typeof(DispatchWrapper[])) { array_mng_type = typeof(object[]); sub_type = VarEnum.VT_DISPATCH; } else if (array_mng_type == typeof(ErrorWrapper[])) { array_mng_type = typeof(int[]); sub_type = VarEnum.VT_ERROR; } else if (array_mng_type == typeof(CurrencyWrapper[])) { array_mng_type = typeof(Decimal[]); sub_type = VarEnum.VT_CY; } else if (array_mng_type == typeof(BStrWrapper[])) { array_mng_type = typeof(string[]); sub_type = VarEnum.VT_BSTR; } } // convert the SafeArraySubType to UnmanagedType UnmanagedType element_unmng_type = Utility.VarEnumToUnmanagedType(sub_type); // determine the element type // (this will have no effect on the C++ signature but we will check it and add it to log) this.elementType = NativeType.FromClrArrayElement( array_mng_type, element_unmng_type, (desc.Flags & ~MarshalFlags.ByRefParam) | MarshalFlags.ComInterop); if (sub_type == VarEnum.VT_EMPTY) { sub_type = Utility.TypeToVarEnum(array_mng_type.GetElementType()); } if (!elementType.IsInvalid) { if (array_mng_type != typeof(System.Array) || sub_type != VarEnum.VT_EMPTY) { // log the element native type Log.Add(Errors.INFO_SafeArrayWillMarshalAs, sub_type.ToString()); } } // also include the *Wrapper hint if applicable if (desc.Type == typeof(object[]) && (sub_type == VarEnum.VT_EMPTY || sub_type == VarEnum.VT_VARIANT)) { Log.Add(Errors.INFO_SafeArrayOfVariantsWrapperUse); } ExplainMemoryManagement(desc, Resources._SafeArray); }
/// <summary> /// Initializes the array as a <see cref="UnmanagedType.LPArray"/>. /// </summary> private void InitializeAsNativeArray(NativeTypeDesc desc) { this.arrayKind = ArrayKind.NativeArray; if (desc.IsByRefParam) { // SizeConst and SizeParamIndex are not allowed for byref if (HasSizeConst(desc) || HasSizeParamIndex(desc)) { Log.Add(Errors.ERROR_ArraySizeNotAllowedForByref); } } else if (!desc.IsCallbackParam) { // when marshaling from managed to native, size is implicit (warn if given explicitly) if (HasSizeConst(desc) || HasSizeParamIndex(desc)) { Log.Add(Errors.WARN_ArraySizesIgnored); } else { Log.Add(Errors.INFO_ArraySizeDeterminedDynamically); } } else { // when marshaling from native to managed, size must be given, otherwise it's 1 if (HasSizeParamIndex(desc)) { Debug.Assert(desc.ParameterInfo != null); ParameterInfo[] parameters = ((MethodBase)desc.ParameterInfo.Member).GetParameters(); int param_index = desc.MarshalAs.SizeParamIndex; if (param_index < 0 || param_index >= parameters.Length) { // index OOR (error) Log.Add(Errors.ERROR_ArraySizeParamIndexOutOfRange, param_index); } else if (!TypeAllowedInSizeParam(parameters[param_index].ParameterType)) { // index refers to bad param (error) Log.Add(Errors.ERROR_ArraySizeParamWrongType,parameters[param_index].ParameterType); } else { // determine parameter name string param_name = parameters[param_index].Name; if (String.IsNullOrEmpty(param_name)) { param_name = String.Format(Resources.Number, param_index + 1); } if (desc.MarshalAs.SizeConst > 0) { // size = [param_at_the_index] + size_const; Log.Add(Errors.INFO_ArraySizeIsByParameterPlusConstant, param_name, desc.MarshalAs.SizeConst); } else { // size = [param_at_the_index] Log.Add(Errors.INFO_ArraySizeIsByParameter, param_name); } } } else if (HasSizeConst(desc)) { // size = size_const Log.Add(Errors.INFO_ArraySizeIsConstant, desc.MarshalAs.SizeConst); } else { // size = 1 (warn) Log.Add(Errors.WARN_ArraySizeDefaultsToOne); } } UnmanagedType element_unmng_type = (desc.MarshalAs == null ? (UnmanagedType)0 : desc.MarshalAs.ArraySubType); if (element_unmng_type == (UnmanagedType)80) element_unmng_type = (UnmanagedType)0; // determine the element type this.elementType = NativeType.FromClrArrayElement(desc.Type, element_unmng_type, desc.Flags); ExplainMemoryManagement(desc, Resources._Array); }
/// <summary> /// Initializes the array as a <see cref="UnmanagedType.ByValArray"/>. /// </summary> private void InitializeAsByValArray(NativeTypeDesc desc) { Debug.Assert(this.indirections == 0); this.arrayKind = ArrayKind.ByValArray; // const size must be specified and >0 if (desc.MarshalAs == null || desc.MarshalAs.SizeConst <= 0) { Log.Add(Errors.ERROR_ByValArrayInvalidLength); this.length = 1; } else { // no need to output any INFO as this number will be between brackets in the code this.length = desc.MarshalAs.SizeConst; } UnmanagedType element_unmng_type = (desc.MarshalAs == null ? (UnmanagedType)0 : desc.MarshalAs.ArraySubType); if (element_unmng_type == (UnmanagedType)80) element_unmng_type = (UnmanagedType)0; // determine the element type this.elementType = NativeType.FromClrArrayElement(desc.Type, element_unmng_type, desc.Flags); }
public ArrayNativeType(NativeTypeDesc desc) : base(desc) { Debug.Assert(desc.Type.IsArray || desc.Type == typeof(System.Array)); this.platform64bit = desc.IsPlatform64Bit; this.indirections = (desc.IsByRefParam ? 1 : 0); this.isInOnly = (!desc.IsByRefParam && !desc.MarshalsOut); // byval and either [In] or default if (!desc.IsStructField) this.isByrefParameter = true; UnmanagedType[] allowed_unmanaged_types; if (desc.Type == typeof(System.Array)) { // System.Array if (desc.IsStructField) { // interface ptr, SAFEARRAY, or by-val array allowed_unmanaged_types = MarshalType.ArrayClassField; } else { // interface ptr or SAFEARRAY allowed_unmanaged_types = MarshalType.ArrayClass; } } else { if (desc.IsArrayElement) { Log.Add(Errors.ERROR_NoNestedArrayMarshaling); this.arrayKind = ArrayKind.Invalid; return; } // an array if (desc.IsStructField) { // default array field marshaling is always COM style, i.e. SAFEARRAY by default allowed_unmanaged_types = MarshalType.ArrayField; } else { // default array parameter marshaling depends on whether we do COM or P/Invoke allowed_unmanaged_types = (desc.IsComInterop ? MarshalType.ArrayC : MarshalType.ArrayP); } } // there are three possible unmanaged types for arrays: switch (ValidateUnmanagedType(desc, allowed_unmanaged_types)) { case UnmanagedType.SafeArray: { InitializeAsSafeArray(desc); break; } case UnmanagedType.LPArray: { InitializeAsNativeArray(desc); break; } case UnmanagedType.ByValArray: { // this unmanaged type only makes sense when we are a field of a type with layout Debug.Assert(desc.IsStructField); InitializeAsByValArray(desc); break; } default: { // interfaces are handled by InterfaceNativeType Debug.Fail(null); break; } } }
/// <summary> /// Initializes the array as a <see cref="UnmanagedType.LPArray"/>. /// </summary> private void InitializeAsNativeArray(NativeTypeDesc desc) { this.arrayKind = ArrayKind.NativeArray; if (desc.IsByRefParam) { // SizeConst and SizeParamIndex are not allowed for byref if (HasSizeConst(desc) || HasSizeParamIndex(desc)) { Log.Add(Errors.ERROR_ArraySizeNotAllowedForByref); } } else if (!desc.IsCallbackParam) { // when marshaling from managed to native, size is implicit (warn if given explicitly) if (HasSizeConst(desc) || HasSizeParamIndex(desc)) { Log.Add(Errors.WARN_ArraySizesIgnored); } else { Log.Add(Errors.INFO_ArraySizeDeterminedDynamically); } } else { // when marshaling from native to managed, size must be given, otherwise it's 1 if (HasSizeParamIndex(desc)) { Debug.Assert(desc.ParameterInfo != null); ParameterInfo[] parameters = ((MethodBase)desc.ParameterInfo.Member).GetParameters(); int param_index = desc.MarshalAs.SizeParamIndex; if (param_index < 0 || param_index >= parameters.Length) { // index OOR (error) Log.Add(Errors.ERROR_ArraySizeParamIndexOutOfRange, param_index); } else if (!TypeAllowedInSizeParam(parameters[param_index].ParameterType)) { // index refers to bad param (error) Log.Add(Errors.ERROR_ArraySizeParamWrongType, parameters[param_index].ParameterType); } else { // determine parameter name string param_name = parameters[param_index].Name; if (String.IsNullOrEmpty(param_name)) { param_name = String.Format(Resources.Number, param_index + 1); } if (desc.MarshalAs.SizeConst > 0) { // size = [param_at_the_index] + size_const; Log.Add(Errors.INFO_ArraySizeIsByParameterPlusConstant, param_name, desc.MarshalAs.SizeConst); } else { // size = [param_at_the_index] Log.Add(Errors.INFO_ArraySizeIsByParameter, param_name); } } } else if (HasSizeConst(desc)) { // size = size_const Log.Add(Errors.INFO_ArraySizeIsConstant, desc.MarshalAs.SizeConst); } else { // size = 1 (warn) Log.Add(Errors.WARN_ArraySizeDefaultsToOne); } } UnmanagedType element_unmng_type = (desc.MarshalAs == null ? (UnmanagedType)0 : desc.MarshalAs.ArraySubType); if (element_unmng_type == (UnmanagedType)80) { element_unmng_type = (UnmanagedType)0; } // determine the element type this.elementType = NativeType.FromClrArrayElement(desc.Type, element_unmng_type, desc.Flags); ExplainMemoryManagement(desc, Resources._Array); }
public ArrayNativeType(NativeTypeDesc desc) : base(desc) { Debug.Assert(desc.Type.IsArray || desc.Type == typeof(System.Array)); this.platform64bit = desc.IsPlatform64Bit; this.indirections = (desc.IsByRefParam ? 1 : 0); this.isInOnly = (!desc.IsByRefParam && !desc.MarshalsOut); // byval and either [In] or default if (!desc.IsStructField) { this.isByrefParameter = true; } UnmanagedType[] allowed_unmanaged_types; if (desc.Type == typeof(System.Array)) { // System.Array if (desc.IsStructField) { // interface ptr, SAFEARRAY, or by-val array allowed_unmanaged_types = MarshalType.ArrayClassField; } else { // interface ptr or SAFEARRAY allowed_unmanaged_types = MarshalType.ArrayClass; } } else { if (desc.IsArrayElement) { Log.Add(Errors.ERROR_NoNestedArrayMarshaling); this.arrayKind = ArrayKind.Invalid; return; } // an array if (desc.IsStructField) { // default array field marshaling is always COM style, i.e. SAFEARRAY by default allowed_unmanaged_types = MarshalType.ArrayField; } else { // default array parameter marshaling depends on whether we do COM or P/Invoke allowed_unmanaged_types = (desc.IsComInterop ? MarshalType.ArrayC : MarshalType.ArrayP); } } // there are three possible unmanaged types for arrays: switch (ValidateUnmanagedType(desc, allowed_unmanaged_types)) { case UnmanagedType.SafeArray: { InitializeAsSafeArray(desc); break; } case UnmanagedType.LPArray: { InitializeAsNativeArray(desc); break; } case UnmanagedType.ByValArray: { // this unmanaged type only makes sense when we are a field of a type with layout Debug.Assert(desc.IsStructField); InitializeAsByValArray(desc); break; } default: { // interfaces are handled by InterfaceNativeType Debug.Fail(null); break; } } }