开发者

C# Define custom UnmanagedType for the MarshalAs attribute class

开发者 https://www.devze.com 2023-04-09 07:32 出处:网络
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:

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号