protected ArrayMarshalInfoWriter(ArrayType type, MarshalType marshalType, MarshalInfo marshalInfo) : base(type) { this._marshalInfo = marshalInfo; this._marshalType = marshalType; this._arrayType = type; this._elementType = type.ElementType; MarshalInfo info = null; ArrayMarshalInfo info2 = marshalInfo as ArrayMarshalInfo; FixedArrayMarshalInfo info3 = marshalInfo as FixedArrayMarshalInfo; this._arraySize = 1; this._nativeElementType = NativeType.None; if (info2 != null) { this._arraySize = info2.Size; this._sizeParameterIndex = info2.SizeParameterIndex; if ((this._arraySize == 0) || ((this._arraySize == -1) && (this._sizeParameterIndex >= 0))) { this._arraySizeSelection = ArraySizeOptions.UseSizeParameterIndex; } else { this._arraySizeSelection = ArraySizeOptions.UseArraySize; } this._nativeElementType = info2.ElementType; info = new MarshalInfo(this._nativeElementType); } else if (info3 != null) { this._arraySize = info3.Size; this._nativeElementType = info3.ElementType; info = new MarshalInfo(this._nativeElementType); } if (this._arraySize == -1) { this._arraySize = 1; } this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(this._elementType, marshalType, info, false, false, true, null); if (this._elementTypeMarshalInfoWriter.MarshaledTypes.Length > 1) { throw new InvalidOperationException($"ArrayMarshalInfoWriter cannot marshal arrays of {this._elementType.FullName}."); } this._arrayMarshaledTypeName = this._elementTypeMarshalInfoWriter.MarshaledTypes[0].DecoratedName + "*"; if (marshalType == MarshalType.WindowsRuntime) { string name = DefaultMarshalInfoWriter.Naming.ForVariable(DefaultMarshalInfoWriter.TypeProvider.UInt32TypeReference); this._arraySizeSelection = ArraySizeOptions.UseFirstMarshaledType; this._marshaledTypes = new MarshaledType[] { new MarshaledType(name, name, "ArraySize"), new MarshaledType(this._arrayMarshaledTypeName, this._arrayMarshaledTypeName) }; } else { this._marshaledTypes = new MarshaledType[] { new MarshaledType(this._arrayMarshaledTypeName, this._arrayMarshaledTypeName) }; } StringMarshalInfoWriter writer = this._elementTypeMarshalInfoWriter as StringMarshalInfoWriter; if (writer != null) { this._nativeElementType = writer.NativeType; } }
void WriteNativeType(NativeType nativeType, MarshalInfo marshalInfo = null) { switch (nativeType) { case NativeType.None: break; case NativeType.Boolean: output.Write("bool"); break; case NativeType.I1: output.Write("int8"); break; case NativeType.U1: output.Write("unsigned int8"); break; case NativeType.I2: output.Write("int16"); break; case NativeType.U2: output.Write("unsigned int16"); break; case NativeType.I4: output.Write("int32"); break; case NativeType.U4: output.Write("unsigned int32"); break; case NativeType.I8: output.Write("int64"); break; case NativeType.U8: output.Write("unsigned int64"); break; case NativeType.R4: output.Write("float32"); break; case NativeType.R8: output.Write("float64"); break; case NativeType.LPStr: output.Write("lpstr"); break; case NativeType.Int: output.Write("int"); break; case NativeType.UInt: output.Write("unsigned int"); break; case NativeType.Func: goto default; // ?? case NativeType.Array: ArrayMarshalInfo ami = (ArrayMarshalInfo)marshalInfo; if (ami == null) { goto default; } if (ami.ElementType != NativeType.Max) { WriteNativeType(ami.ElementType); } output.Write('['); if (ami.SizeParameterMultiplier == 0) { output.Write(ami.Size.ToString()); } else { if (ami.Size >= 0) { output.Write(ami.Size.ToString()); } output.Write(" + "); output.Write(ami.SizeParameterIndex.ToString()); } output.Write(']'); break; case NativeType.Currency: output.Write("currency"); break; case NativeType.BStr: output.Write("bstr"); break; case NativeType.LPWStr: output.Write("lpwstr"); break; case NativeType.LPTStr: output.Write("lptstr"); break; case NativeType.FixedSysString: output.Write("fixed sysstring[{0}]", ((FixedSysStringMarshalInfo)marshalInfo).Size); break; case NativeType.IUnknown: output.Write("iunknown"); break; case NativeType.IDispatch: output.Write("idispatch"); break; case NativeType.Struct: output.Write("struct"); break; case NativeType.IntF: output.Write("interface"); break; case NativeType.SafeArray: output.Write("safearray "); SafeArrayMarshalInfo sami = marshalInfo as SafeArrayMarshalInfo; if (sami != null) { switch (sami.ElementType) { case VariantType.None: break; case VariantType.I2: output.Write("int16"); break; case VariantType.I4: output.Write("int32"); break; case VariantType.R4: output.Write("float32"); break; case VariantType.R8: output.Write("float64"); break; case VariantType.CY: output.Write("currency"); break; case VariantType.Date: output.Write("date"); break; case VariantType.BStr: output.Write("bstr"); break; case VariantType.Dispatch: output.Write("idispatch"); break; case VariantType.Error: output.Write("error"); break; case VariantType.Bool: output.Write("bool"); break; case VariantType.Variant: output.Write("variant"); break; case VariantType.Unknown: output.Write("iunknown"); break; case VariantType.Decimal: output.Write("decimal"); break; case VariantType.I1: output.Write("int8"); break; case VariantType.UI1: output.Write("unsigned int8"); break; case VariantType.UI2: output.Write("unsigned int16"); break; case VariantType.UI4: output.Write("unsigned int32"); break; case VariantType.Int: output.Write("int"); break; case VariantType.UInt: output.Write("unsigned int"); break; default: output.Write(sami.ElementType.ToString()); break; } } break; case NativeType.FixedArray: output.Write("fixed array"); FixedArrayMarshalInfo fami = marshalInfo as FixedArrayMarshalInfo; if (fami != null) { output.Write("[{0}]", fami.Size); if (fami.ElementType != NativeType.None) { output.Write(' '); WriteNativeType(fami.ElementType); } } break; case NativeType.ByValStr: output.Write("byvalstr"); break; case NativeType.ANSIBStr: output.Write("ansi bstr"); break; case NativeType.TBStr: output.Write("tbstr"); break; case NativeType.VariantBool: output.Write("variant bool"); break; case NativeType.ASAny: output.Write("as any"); break; case NativeType.LPStruct: output.Write("lpstruct"); break; case NativeType.CustomMarshaler: CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo; if (cmi == null) { goto default; } output.Write("custom(\"{0}\", \"{1}\"", CSharp.OutputVisitor.ConvertString(cmi.ManagedType.FullName), CSharp.OutputVisitor.ConvertString(cmi.Cookie)); if (cmi.Guid != Guid.Empty || !string.IsNullOrEmpty(cmi.UnmanagedType)) { output.Write(", \"{0}\", \"{1}\"", cmi.Guid.ToString(), CSharp.OutputVisitor.ConvertString(cmi.UnmanagedType)); } output.Write(')'); break; case NativeType.Error: output.Write("error"); break; default: output.Write(nativeType.ToString()); break; } }