public static object GetValueAt(int vt, IntPtr addr) { object obj = null; switch ((VarEnum)vt) { case VarEnum.VT_I1: obj = (sbyte)Marshal.ReadByte(addr); break; case VarEnum.VT_UI1: obj = Marshal.ReadByte(addr); break; case VarEnum.VT_I2: obj = Marshal.ReadInt16(addr); break; case VarEnum.VT_UI2: obj = (ushort)Marshal.ReadInt16(addr); break; case VarEnum.VT_ERROR: case VarEnum.VT_INT: case VarEnum.VT_I4: obj = Marshal.ReadInt32(addr); break; case VarEnum.VT_UINT: case VarEnum.VT_UI4: obj = (uint)Marshal.ReadInt32(addr); break; case VarEnum.VT_I8: obj = Marshal.ReadInt64(addr); break; case VarEnum.VT_UI8: obj = (ulong)Marshal.ReadInt64(addr); break; case VarEnum.VT_R4: obj = Marshal.PtrToStructure(addr, typeof(float)); break; case VarEnum.VT_R8: obj = Marshal.PtrToStructure(addr, typeof(double)); break; case VarEnum.VT_BOOL: obj = !(Marshal.ReadInt16(addr) == 0); break; case VarEnum.VT_BSTR: { IntPtr ptr = Marshal.ReadIntPtr(addr); if (ptr != IntPtr.Zero) { obj = Marshal.PtrToStringBSTR(ptr); } else { obj = null; } break; } case VarEnum.VT_CY: obj = Decimal.FromOACurrency(Marshal.ReadInt64(addr)); break; case VarEnum.VT_DATE: obj = DateTime.FromOADate((double)Marshal.PtrToStructure(addr, typeof(double))); break; case VarEnum.VT_DECIMAL: { DECIMAL *dec = (DECIMAL *)addr; obj = new Decimal((int)dec->Lo64, (int)(dec->Lo64 >> 32), dec->Hi32, dec->sign != 0, dec->scale); break; } case VarEnum.VT_RECORD: throw new NotImplementedException("VT_RECORD not implemented"); // GetObjectForIUnknown is excluded from Marshal using FULL_AOT_RUNTIME #if !DISABLE_COM case VarEnum.VT_UNKNOWN: case VarEnum.VT_DISPATCH: { IntPtr ifaceaddr = Marshal.ReadIntPtr(addr); if (ifaceaddr != IntPtr.Zero) { obj = Marshal.GetObjectForIUnknown(ifaceaddr); } break; } #endif case VarEnum.VT_VARIANT: { Variant v = *((Variant *)addr); obj = v.GetValue(); break; } default: if (((VarEnum)vt & VarEnum.VT_ARRAY) != 0) { obj = SafeArrayToArrayInternal(*((IntPtr *)addr), vt & ~(short)VarEnum.VT_ARRAY); } break; } return(obj); }
public static void SetValueAt(object obj, int vt, IntPtr addr) { Type t = obj.GetType(); switch ((VarEnum)vt) { case VarEnum.VT_I1: *((sbyte *)addr) = (sbyte)obj; break; case VarEnum.VT_UI1: *((byte *)addr) = (byte)obj; break; case VarEnum.VT_I2: *((short *)addr) = (short)obj; break; case VarEnum.VT_UI2: *((ushort *)addr) = (ushort)obj; break; case VarEnum.VT_INT: case VarEnum.VT_I4: *((int *)addr) = (int)obj; break; case VarEnum.VT_UINT: case VarEnum.VT_UI4: *((uint *)addr) = (uint)obj; break; case VarEnum.VT_I8: *((long *)addr) = (long)obj; break; case VarEnum.VT_UI8: *((ulong *)addr) = (ulong)obj; break; case VarEnum.VT_R4: *((float *)addr) = (float)obj; break; case VarEnum.VT_R8: *((double *)addr) = (double)obj; break; case VarEnum.VT_BOOL: *((short *)addr) = (short)((bool)obj ? -1 : 0); break; case VarEnum.VT_BSTR: if (t == typeof(BStrWrapper)) { *((IntPtr *)addr) = Marshal.StringToBSTR(((BStrWrapper)obj).WrappedObject); } else { *((IntPtr *)addr) = Marshal.StringToBSTR((string)obj); } break; case VarEnum.VT_CY: if (t == typeof(CurrencyWrapper)) { *((long *)addr) = Decimal.ToOACurrency(((CurrencyWrapper)obj).WrappedObject); } else { *((long *)addr) = Decimal.ToOACurrency((Decimal)obj); } break; case VarEnum.VT_DATE: *((double *)addr) = ((DateTime)obj).ToOADate(); break; case VarEnum.VT_DECIMAL: { int[] parts = Decimal.GetBits((Decimal)obj); DECIMAL *dec = (DECIMAL *)addr; dec->scale = (byte)((parts[3] >> 16) & 0x7F); dec->sign = (byte)(parts[3] >> 24); dec->Hi32 = parts[2]; dec->Lo64 = (uint)parts[0] | ((ulong)(uint)parts[1] << 32); break; } case VarEnum.VT_ERROR: if (t == typeof(ErrorWrapper)) { *((int *)addr) = ((ErrorWrapper)obj).ErrorCode; } else { *((int *)addr) = (int)obj; } break; case VarEnum.VT_VARIANT: { Variant v = default(Variant); v.SetValue(obj); *((Variant *)addr) = v; break; } #if FEATURE_COMINTEROP case VarEnum.VT_UNKNOWN: if (t == typeof(UnknownWrapper)) { *((IntPtr *)addr) = Marshal.GetIUnknownForObject(((UnknownWrapper)obj).WrappedObject); } else { *((IntPtr *)addr) = Marshal.GetIUnknownForObject(obj); } break; case VarEnum.VT_DISPATCH: if (t == typeof(DispatchWrapper)) { *((IntPtr *)addr) = Marshal.GetIDispatchForObject(((DispatchWrapper)obj).WrappedObject); } else { *((IntPtr *)addr) = Marshal.GetIDispatchForObject(obj); } break; #endif default: if (((VarEnum)vt & VarEnum.VT_ARRAY) != 0) { int tmp; *((IntPtr *)addr) = SafeArrayFromArrayInternal((Array)obj, out tmp); break; } throw new NotImplementedException(string.Format("Variant.SetValueAt couldn't handle VT {0}", vt)); } }