C # Определить пользовательский UnmanagedType для класса атрибута MarshalAs - PullRequest
1 голос
/ 30 сентября 2011

возможно ли определить пользовательский тип UnmanagedType для класса атрибутов MarshalAs?В частности, я хочу преобразовать длинное время 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 и написать преобразование в этот класс?Спасибо, Юрген

Обновление Вот пользовательский маршаллер:

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!) Невозможно упорядочить поле 'CurrentTime' типа 'QFX_DLL.MT5ServerAttributes':Недопустимая комбинация управляемого / неуправляемого типа (класс DateTime должен быть связан со Struct).Есть идеи?

1 Ответ

5 голосов
/ 30 сентября 2011

Вы не можете добавить свои собственные в перечисление, но вы можете использовать UnmanagedType.CustomMarshaler. Чтобы указать, что вы хотите упорядочить его, используя пользовательский тип.

MSDN имеет целый раздел, посвященный этому.

В конечном итоге вы сделаете что-то вроде этого:

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

Затем реализуйте MyCustomMarshaler как ICustomMarshaler.

...