コード例 #1
0
ファイル: Variant.cs プロジェクト: nsivov/mono
        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);
        }
コード例 #2
0
ファイル: Variant.cs プロジェクト: nsivov/mono
        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));
            }
        }