namespace System
{
- [StructLayout(LayoutKind.Explicit, Size = 16)]
+ [StructLayout(LayoutKind.Explicit)]
internal unsafe struct Variant
{
[FieldOffset(0)]
[FieldOffset(8)]
public uint uintVal;
- [FieldOffset(8)]
- public IntPtr pdispVal;
+ [FieldOffset(8)]
+ public IntPtr pdispVal;
+
+ [FieldOffset(8)]
+ public BRECORD bRecord;
public void SetValue(object obj) {
vt = (short)VarEnum.VT_EMPTY;
return;
Type t = obj.GetType();
+ if (t.IsEnum)
+ t = Enum.GetUnderlyingType (t);
+
if (t == typeof(sbyte))
{
vt = (short)VarEnum.VT_I1;
{
vt = (short)VarEnum.VT_BSTR;
bstrVal = Marshal.StringToBSTR((string)obj);
- }
- else if (t == typeof(bool))
- {
- vt = (short)VarEnum.VT_BOOL;
- lVal = ((bool)obj) ? -1 : 0;
- }
- else
- {
- try
- {
- vt = (short)VarEnum.VT_DISPATCH;
- pdispVal = Marshal.GetIUnknownForObject(obj);
- }
- catch (Exception ex)
- {
- throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()), ex);
- }
}
+ else if (t == typeof(bool))
+ {
+ vt = (short)VarEnum.VT_BOOL;
+ lVal = ((bool)obj) ? -1 : 0;
+ }
+ else if (t == typeof (BStrWrapper))
+ {
+ vt = (short)VarEnum.VT_BSTR;
+ bstrVal = Marshal.StringToBSTR(((BStrWrapper)obj).WrappedObject);
+ }
+#if FEATURE_COMINTEROP
+ else if (t == typeof (UnknownWrapper))
+ {
+ vt = (short)VarEnum.VT_UNKNOWN;
+ pdispVal = Marshal.GetIUnknownForObject(((UnknownWrapper)obj).WrappedObject);
+ }
+ else if (t == typeof (DispatchWrapper))
+ {
+ vt = (short)VarEnum.VT_DISPATCH;
+ pdispVal = Marshal.GetIDispatchForObject(((DispatchWrapper)obj).WrappedObject);
+ }
+#endif
+ else
+ {
+#if !FEATURE_COMINTEROP
+ throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()));
+#else
+ try
+ {
+ pdispVal = Marshal.GetIDispatchForObject(obj);
+ vt = (short)VarEnum.VT_DISPATCH;
+ return;
+ }
+ catch { }
+ try
+ {
+ vt = (short)VarEnum.VT_UNKNOWN;
+ pdispVal = Marshal.GetIUnknownForObject(obj);
+ }
+ catch (Exception ex)
+ {
+ throw new NotImplementedException(string.Format("Variant couldn't handle object of type {0}", obj.GetType()), ex);
+ }
+#endif
+ }
+ }
+
+ 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_I4:
+ obj = Marshal.ReadInt32(addr);
+ break;
+ 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:
+ obj = Marshal.PtrToStringBSTR(Marshal.ReadIntPtr(addr));
+ break;
+// 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
+ }
+ return obj;
}
public object GetValue() {
obj = dblVal;
break;
case VarEnum.VT_BOOL:
- obj = !(lVal == 0);
+ obj = !(boolVal == 0);
break;
case VarEnum.VT_BSTR:
obj = Marshal.PtrToStringBSTR(bstrVal);
break;
- case VarEnum.VT_UNKNOWN:
- case VarEnum.VT_DISPATCH:
- obj = Marshal.GetObjectForIUnknown(pdispVal);
- break;
+#if FEATURE_COMINTEROP
+ case VarEnum.VT_UNKNOWN:
+ case VarEnum.VT_DISPATCH:
+ if (pdispVal != IntPtr.Zero)
+ obj = Marshal.GetObjectForIUnknown(pdispVal);
+ break;
+#endif
+ default:
+ if (((VarEnum)vt & VarEnum.VT_BYREF) == VarEnum.VT_BYREF &&
+ pdispVal != IntPtr.Zero)
+ {
+ obj = GetValueAt(vt & ~(short)VarEnum.VT_BYREF, pdispVal);
+ }
+ break;
}
return obj;
- }\r
-\r
- public void Clear ()\r
- {\r
- if ((VarEnum)vt == VarEnum.VT_BSTR) {\r
- Marshal.FreeBSTR (bstrVal);\r
- }\r
- else if ((VarEnum)vt == VarEnum.VT_DISPATCH || (VarEnum)vt == VarEnum.VT_UNKNOWN) {\r
- if (pdispVal != IntPtr.Zero)\r
+ }
+
+ public void Clear ()
+ {
+ if ((VarEnum)vt == VarEnum.VT_BSTR) {
+ Marshal.FreeBSTR (bstrVal);
+ }
+#if !DISABLE_COM
+ else if ((VarEnum)vt == VarEnum.VT_DISPATCH || (VarEnum)vt == VarEnum.VT_UNKNOWN) {
+ if (pdispVal != IntPtr.Zero)
Marshal.Release (pdispVal);
- }
+ }
+#endif
}
}
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe struct BRECORD
+ {
+ #pragma warning disable 169
+ IntPtr pvRecord;
+ IntPtr pRecInfo;
+ #pragma warning restore 169
+ }
}