is it possible to define a custom UnmanagedType for the MarshalAs attribute class? Specifically I want to convert a long int unix time into a DateTime type. Something like this:
[MarshalAs(UnmanagedType.LongTimeUnix)]
public DateTime Time;
Where do I have to put the custom LongTimeUnix enumeration type and where to put the time conversion code:
public static DateTime ConvertUnix2DateTime(long timeStamp)
{
DateTime DT = new DateTime(1970, 1, 1, 0, 0, 0, 0);
DT = DT.AddSeconds(timeStamp);
return DT;
}
When transferring the data with
(SomeStruct)Marshal.PtrToStructure(
IntPtr,
typeof(SomeStruct));
I want that the long time unix is automatically converted with the code sinppet above. Do I have to inherit from the MarshalAs class and write the conversion into this class? Thanks, Juergen
Update Here is the custom marshaller:
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;
}
}
Here is the class definition:
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;
}
And finally the code to marshal the data from unmanaged memory:
try
{
MT5ServerAttributes MT5SrvAttributes = (MT5ServerAttributes)Marshal.PtrToStructure(mMT5Proxy.MT5InformationProxy.ServerData,开发者_JAVA技巧
typeof(MT5ServerAttributes));
}
catch (Exception e)
{
QFXLogger.Error(e, "ConsumeCommand inner");
}
When running this the following excpetion is thrown(which is not a direct exception ot PtrToStructure!) Cannot marshal field 'CurrentTime' of type 'QFX_DLL.MT5ServerAttributes': Invalid managed/unmanaged type combination (the DateTime class must be paired with Struct). Any ideas?
You cannot add your own to the enumeration, but you can use UnmanagedType.CustomMarshaler
. To specify that you want to marshal it using a custom type.
MSDN has an entire section dedicated to this.
You would end up doing something along these lines:
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(MyCustomMarshaler))]
public DateTime Time;
Then implement MyCustomMarshaler as ICustomMarshaler
.
精彩评论