public static bool TryGetMetadataByName(this IWICMetadataQueryReader meta, string name, out PropVariant value) { value = null; int hr = ProxyFunctions.GetMetadataByName(meta, name, IntPtr.Zero); if (hr >= 0) { value = new PropVariant(); var pvMarshal = new PropVariant.Marshaler(); var pvNative = pvMarshal.MarshalManagedToNative(value); hr = ProxyFunctions.GetMetadataByName(meta, name, pvNative); pvMarshal.MarshalNativeToManaged(pvNative); pvMarshal.CleanUpNativeData(pvNative); } return(hr >= 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); }
public static bool TrySetMetadataByName(this IWICMetadataQueryWriter meta, string name, PropVariant value) { var pvMarshal = new PropVariant.Marshaler(); var pvNative = pvMarshal.MarshalManagedToNative(value); int hr = ProxyFunctions.SetMetadataByName(meta, name, pvNative); pvMarshal.CleanUpNativeData(pvNative); return(hr >= 0); }