2011-09-30 32 views
1

是否可以为MarshalAs属性类定义自定义UnmanagedType? 具体而言,我想将一个long int unix时间转换为DateTime类型。事情是这样的:C#为MarshalAs属性类定义自定义UnmanagedType

[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会自动转换上面的代码sinppet。 是否必须从MarshalAs类继承并将转换写入此类? 谢谢,克林斯曼

更新 这是自定义编组:

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.MT5ServerAttributes'的字段'CurrentTime':无效的托管/非托管类型组合(DateTime类必须与结构)。 任何想法?

回答

4

您无法将其自己添加到枚举中,但可以使用UnmanagedType.CustomMarshaler。指定您想要使用自定义类型进行编组。

MSDN有一整段专用于此。

你最终会沿着这些路线做的事情:

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

然后实现MyCustomMarshaler为ICustomMarshaler

+0

谢谢,我会试试这个。 – Juergen

+1

这是否真的有用?我正在尝试,因为你不能在类成员上使用'CustomMarshaler',所以失败了。据我可以告诉'CustomMarshaler'只适用于函数参数(这很痛苦)。 –

+3

不,对J.N而言,我不会感到高兴。我怀疑他的评论是@Juergen在实际尝试之前将此标记为答案。如果你跳过调用'Marshal.SizeOf'并直接进入'Marshal.PtrToStructure'调用的步骤,你会得到错误**“自定义封送拆收器不能在结构体的字段上使用。”**这几乎是说它不能完成。 – BTJ