为MarshalAs属性类定义自定义UnmanagedType



是否可以为MarshalAs属性类定义一个自定义的UnmanagedType ?具体来说,我想将一个长int unix时间转换为DateTime类型。像这样:

[MarshalAs(UnmanagedType.LongTimeUnix)]
public DateTime Time;

我必须在哪里放置自定义LongTimeUnix枚举类型,以及在哪里放置时间转换代码:

public static DateTime ConvertUnix2DateTime(long timeStamp)
{
        DateTime DT = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        DT = DT.AddSeconds(timeStamp);
        return DT;
}

使用

传输数据时
(SomeStruct)Marshal.PtrToStructure(
 IntPtr,
 typeof(SomeStruct));

我希望长时间unix自动转换为上面的代码。我是否必须继承MarshalAs类并将转换写入该类?谢谢,Juergen

以下是自定义编组器:

class MarshalTest : ICustomMarshaler
{
    public void CleanUpManagedData(object ManagedObj)
    {
        throw new NotImplementedException();
    }
    public void CleanUpNativeData(IntPtr pNativeData)
    {
        throw new NotImplementedException();
    }
    public int GetNativeDataSize()
    {
        return 8;
    }
    public IntPtr MarshalManagedToNative(object ManagedObj)
    {
        throw new NotImplementedException();
    }
    public object MarshalNativeToManaged(IntPtr pNativeData)
    {
        long UnixTime = 0;
        try
        {
            UnixTime = Marshal.ReadInt64(pNativeData);
        }
        catch (Exception e)
        {
           QFXLogger.Error(e, "MarshalNativeToManaged");
        }
        DateTime DT = new DateTime(1970, 1, 1, 0, 0, 0, 0);
        DT = DT.AddSeconds(UnixTime);
        return DT;
    }
 }

下面是类定义:

unsafe public struct MT5ServerAttributes
{
    /// <summary>
    /// Last known server time.
    /// </summary>
    [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MarshalTest))]
    public DateTime CurrentTime;
    //[MarshalAs(UnmanagedType.U8)]
    [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MarshalTest))]
    public DateTime TradeTime;
 }

最后是封送来自非托管内存的数据的代码:

try
{
   MT5ServerAttributes MT5SrvAttributes = (MT5ServerAttributes)Marshal.PtrToStructure(mMT5Proxy.MT5InformationProxy.ServerData,
                                                                    typeof(MT5ServerAttributes));
}
catch (Exception e)
{
QFXLogger.Error(e, "ConsumeCommand inner");
}

当运行这个时,抛出以下异常(这不是PtrToStructure的直接异常!)无法封送'QFX_DLL '类型的'CurrentTime'字段。MT5ServerAttributes':无效的托管/非托管类型组合(DateTime类必须与Struct配对)。什么好主意吗?

您不能将自己的枚举添加到枚举中,但可以使用UnmanagedType.CustomMarshaler。要指定要使用自定义类型封送它。

MSDN有一个完整的部分专门用于此。

你最终会这样做:

[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyCustomMarshaler))]
public DateTime Time;

然后实现MyCustomMarshaler作为ICustomMarshaler

最新更新