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