Пример #1
0
        public object MarshalNativeToManaged(IntPtr pNativeData)
        {
            if ((IntPtr.Zero == pNativeData) || (null == propVariantReference))
            {
                return(null);
            }

            UnmanagedPropVariant unmanagedPropVariant = new UnmanagedPropVariant();

            Marshal.PtrToStructure(pNativeData, unmanagedPropVariant);

            if ((0 == (unmanagedPropVariant.vt & (ushort)VarEnum.VT_VECTOR)) && (unmanagedPropVariant.vt != (ushort)VarEnum.VT_BLOB))
            {
                switch ((VarEnum)unmanagedPropVariant.vt)
                {
                case VarEnum.VT_CLSID:
                {
                    if (unmanagedPropVariant.vectorValue.ptr != IntPtr.Zero)
                    {
                        propVariantReference.value = To <Guid>(unmanagedPropVariant.vectorValue.ptr);
                    }
                    return(null);
                }

                case VarEnum.VT_EMPTY:
                {
                    propVariantReference.value       = null;
                    propVariantReference.marshalType = PropVariantMarshalType.Automatic;
                    return(null);
                }

                case VarEnum.VT_LPSTR:
                {
                    propVariantReference.value       = Marshal.PtrToStringAnsi(unmanagedPropVariant.pointerValue);
                    propVariantReference.marshalType = PropVariantMarshalType.Ascii;
                    return(null);
                }

                case VarEnum.VT_LPWSTR:
                {
                    propVariantReference.value       = Marshal.PtrToStringUni(unmanagedPropVariant.pointerValue);
                    propVariantReference.marshalType = PropVariantMarshalType.Automatic;
                    return(null);
                }

                case VarEnum.VT_FILETIME:
                {
                    propVariantReference.value       = DateTime.FromFileTimeUtc(unmanagedPropVariant.int64Value);
                    propVariantReference.marshalType = PropVariantMarshalType.Automatic;
                    return(null);
                }

                default:
                {
                    propVariantReference.value       = Marshal.GetObjectForNativeVariant(pNativeData);
                    propVariantReference.marshalType = PropVariantMarshalType.Automatic;
                    return(null);
                }
                }
            }
            else
            {
                VarEnum elementVt = (VarEnum)(unmanagedPropVariant.vt & ~(ushort)VarEnum.VT_VECTOR);
                int     count     = (int)unmanagedPropVariant.vectorValue.count;
                propVariantReference.marshalType = PropVariantMarshalType.Automatic;

                switch (elementVt)
                {
                case VarEnum.VT_BLOB:
                    propVariantReference.marshalType = PropVariantMarshalType.Blob;
                    propVariantReference.value       = ToArrayOf <byte>(unmanagedPropVariant.vectorValue.ptr, count);;
                    break;

                case VarEnum.VT_I1:
                    propVariantReference.value = ToArrayOf <sbyte>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_UI1:
                    propVariantReference.value = ToArrayOf <byte>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_I2:
                    propVariantReference.value = ToArrayOf <short>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_UI2:
                    propVariantReference.value = ToArrayOf <ushort>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_I4:
                    propVariantReference.value = ToArrayOf <int>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_UI4:
                    propVariantReference.value = ToArrayOf <uint>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_R4:
                    propVariantReference.value = ToArrayOf <float>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_UI8:
                    propVariantReference.value = ToArrayOf <ulong>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_I8:
                    propVariantReference.value = ToArrayOf <long>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_R8:
                    propVariantReference.value = ToArrayOf <double>(unmanagedPropVariant.vectorValue.ptr, count);
                    break;

                case VarEnum.VT_LPWSTR:
                    propVariantReference.marshalType = PropVariantMarshalType.Automatic;
                    propVariantReference.value       = GetArrayOfStrings(unmanagedPropVariant.vectorValue.ptr, count, Marshal.PtrToStringUni);
                    break;

                case VarEnum.VT_LPSTR:
                    propVariantReference.marshalType = PropVariantMarshalType.Ascii;
                    propVariantReference.value       = GetArrayOfStrings(unmanagedPropVariant.vectorValue.ptr, count, Marshal.PtrToStringAnsi);
                    break;

                default: throw new NotImplementedException();
                }

                return(null);
            }
        }
Пример #2
0
        public IntPtr MarshalManagedToNative(object obj)
        {
            if (null == obj)
            {
                return(IntPtr.Zero);
            }


            PropVariantMarshalType marshalType = PropVariantMarshalType.Automatic;

            if (obj is PropVariant)
            {
                propVariantReference = (PropVariant)obj;
                obj         = propVariantReference.Value;
                marshalType = propVariantReference.MarshalType;
            }

            IntPtr pNativeData = AllocatePropVariant();

            if (null == obj)
            {
            }
            else if (!(obj is Array))
            {
                if (marshalType == PropVariantMarshalType.Ascii)
                {
                    UnmanagedPropVariant upv = new UnmanagedPropVariant();
                    upv.vt           = (ushort)VarEnum.VT_LPSTR;
                    upv.pointerValue = Marshal.StringToCoTaskMemAnsi((string)obj);
                    Marshal.StructureToPtr(upv, pNativeData, false);
                }
                else if (obj is DateTime)
                {
                    UnmanagedPropVariant upv = new UnmanagedPropVariant();
                    upv.vt         = (ushort)VarEnum.VT_FILETIME;
                    upv.int64Value = ((DateTime)obj).ToFileTimeUtc();
                    Marshal.StructureToPtr(upv, pNativeData, false);
                }
                else if (obj is string)
                {
                    UnmanagedPropVariant upv = new UnmanagedPropVariant();
                    upv.vt           = (ushort)VarEnum.VT_LPWSTR;
                    upv.pointerValue = Marshal.StringToCoTaskMemUni((string)obj);
                    Marshal.StructureToPtr(upv, pNativeData, false);
                }
                else
                {
                    Marshal.GetNativeVariantForObject(obj, pNativeData);
                }
            }
            else if ((obj.GetType().Equals(typeof(byte[]))) || (obj.GetType().Equals(typeof(sbyte[]))) ||
                     (obj.GetType().Equals(typeof(Int16[]))) || (obj.GetType().Equals(typeof(UInt16[]))) ||
                     (obj.GetType().Equals(typeof(Int32[]))) || (obj.GetType().Equals(typeof(UInt32[]))) ||
                     (obj.GetType().Equals(typeof(Int64[]))) || (obj.GetType().Equals(typeof(UInt64[]))) ||
                     (obj.GetType().Equals(typeof(float[]))) || (obj.GetType().Equals(typeof(double[]))))
            {
                int    count         = ((Array)obj).Length;
                int    elementSize   = Marshal.SizeOf(obj.GetType().GetElementType());
                IntPtr pNativeBuffer = Marshal.AllocCoTaskMem(elementSize * count);

                for (int i = 0; i < count; i++)
                {
                    IntPtr pNativeValue = Marshal.UnsafeAddrOfPinnedArrayElement((Array)obj, i);
                    for (int j = 0; j < elementSize; j++)
                    {
                        byte value = Marshal.ReadByte(pNativeValue, j);
                        Marshal.WriteByte(pNativeBuffer, j + i * elementSize, value);
                    }
                }

                UnmanagedPropVariant upv = new UnmanagedPropVariant();
                upv.vectorValue.count = (uint)count;
                upv.vectorValue.ptr   = pNativeBuffer;
                if (null == propVariantReference)
                {
                    upv.vt = (ushort)(new PropVariant(obj)).GetUnmanagedType();
                }
                else
                {
                    upv.vt = (ushort)propVariantReference.GetUnmanagedType();
                }

                Marshal.StructureToPtr(upv, pNativeData, false);
            }
            else if (obj.GetType().Equals(typeof(string[])))
            {
                int    count         = ((Array)obj).Length;
                IntPtr pNativeBuffer = Marshal.AllocCoTaskMem(IntPtr.Size * count);

                for (int i = 0; i < count; i++)
                {
                    IntPtr strPtr = Marshal.StringToCoTaskMemUni(((string[])obj)[i]);
                    Marshal.WriteIntPtr(pNativeBuffer, IntPtr.Size * i, strPtr);
                }

                UnmanagedPropVariant upv = new UnmanagedPropVariant();
                upv.vectorValue.count = (uint)count;
                upv.vectorValue.ptr   = pNativeBuffer;
                if (null == propVariantReference)
                {
                    upv.vt = (ushort)(new PropVariant(obj)).GetUnmanagedType();
                }
                else
                {
                    upv.vt = (ushort)propVariantReference.GetUnmanagedType();
                }

                Marshal.StructureToPtr(upv, pNativeData, false);
            }
            else
            {
                throw new NotImplementedException();
            }

            return(pNativeData);
        }