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); }
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); }