Ejemplo n.º 1
0
        /// <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);
        }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <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);
        }