public ComSafeArrayMarshalInfoWriter(ArrayType type, MarshalInfo marshalInfo) : base(type) { this._elementType = type.ElementType; this._marshalInfo = marshalInfo as SafeArrayMarshalInfo; if (this._marshalInfo == null) { throw new InvalidOperationException($"SafeArray type '{type.FullName}' has invalid MarshalAsAttribute."); } if ((this._marshalInfo.ElementType == VariantType.BStr) && (this._elementType.MetadataType != MetadataType.String)) { throw new InvalidOperationException($"SafeArray(BSTR) type '{type.FullName}' has invalid MarshalAsAttribute."); } NativeType nativeElementType = this.GetNativeElementType(); this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(this._elementType, MarshalType.COM, new MarshalInfo(nativeElementType), false, false, false, null); string name = $"Il2CppSafeArray/*{this._marshalInfo.ElementType.ToString().ToUpper()}*/*"; this._marshaledTypes = new MarshaledType[] { new MarshaledType(name, name) }; }
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; } }