private static T[] toArrayOf <T>(UnmanagedPropVariant pv) where T : struct
            {
                int size = (int)pv.vectorValue.count;
                var res  = new T[size];

                for (int i = 0; i < size; i++)
                {
                    res[i] = Marshal.PtrToStructure <T>(pv.vectorValue.ptr + i * Marshal.SizeOf <T>());
                }

                return(res);
            }
Beispiel #2
0
            public IntPtr MarshalManagedToNative(object o)
            {
                if (o == null)
                {
                    return(IntPtr.Zero);
                }

                var marshalType = PropVariantMarshalType.Automatic;

                if (o is PropVariant)
                {
                    pv          = (PropVariant)o;
                    o           = pv.Value;
                    marshalType = pv.MarshalType;
                }

                var pNativeData = AllocatePropVariant();

                if (o == null)
                {
                    return(pNativeData);
                }

                var type = o.GetType();

                if (!(o is Array))
                {
                    if (marshalType == PropVariantMarshalType.Ascii)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt           = (ushort)VarEnum.VT_LPSTR;
                        upv.pointerValue = Marshal.StringToCoTaskMemAnsi((string)o);
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else if (o is string)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt           = (ushort)VarEnum.VT_LPWSTR;
                        upv.pointerValue = Marshal.StringToCoTaskMemUni((string)o);
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else if (o is DateTime)
                    {
                        var upv = new UnmanagedPropVariant();
                        upv.vt         = (ushort)VarEnum.VT_FILETIME;
                        upv.int64Value = ((DateTime)o).ToFileTimeUtc();
                        Marshal.StructureToPtr(upv, pNativeData, false);
                    }
                    else
                    {
                        Marshal.GetNativeVariantForObject(o, pNativeData);
                    }
                }
                else if ((type.Equals(typeof(byte []))) || (type.Equals(typeof(sbyte []))) ||
                         (type.Equals(typeof(short[]))) || (type.Equals(typeof(ushort[]))) ||
                         (type.Equals(typeof(int  []))) || (type.Equals(typeof(uint  []))) ||
                         (type.Equals(typeof(long []))) || (type.Equals(typeof(ulong []))) ||
                         (type.Equals(typeof(float[]))) || (type.Equals(typeof(double[]))))
                {
                    var a             = (Array)o;
                    int count         = a.Length;
                    int elementSize   = Marshal.SizeOf(type.GetElementType());
                    var pNativeBuffer = Marshal.AllocCoTaskMem(elementSize * count);

                    var gch = GCHandle.Alloc(a, GCHandleType.Pinned);
                    for (int i = 0; i < count; i++)
                    {
                        var pNativeValue = Marshal.UnsafeAddrOfPinnedArrayElement(a, i);
                        for (int j = 0; j < elementSize; j++)
                        {
                            byte value = Marshal.ReadByte(pNativeValue, j);
                            Marshal.WriteByte(pNativeBuffer, elementSize * i + j, value);
                        }
                    }
                    gch.Free();

                    var upv = new UnmanagedPropVariant();
                    upv.vectorValue.count = (uint)count;
                    upv.vectorValue.ptr   = pNativeBuffer;
                    upv.vt = (ushort)(pv ?? new PropVariant(o)).UnmanagedType;

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

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

                    var upv = new UnmanagedPropVariant();
                    upv.vectorValue.count = (uint)count;
                    upv.vectorValue.ptr   = pNativeBuffer;
                    upv.vt = (ushort)(pv ?? new PropVariant(o)).UnmanagedType;

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

                return(pNativeData);
            }