C# 为 MarshalAs 属性类定义自定义 UnmanagedType

标签 c# marshalling unmanaged unix-timestamp

是否可以为 MarshalAs 属性类定义一个自定义的 UnmanagedType? 具体来说,我想将 long 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));

我希望用上面的代码sinppet自动转换长时间的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 的直接异常!) 无法编码“QFX_DLL.MT5ServerAttributes”类型的字段“CurrentTime”:无效的托管/非托管类型组合(DateTime 类必须与 Struct 配对)。 有什么想法吗?

最佳答案

您不能将自己的添加到枚举中,但可以使用 UnmanagedType.CustomMarshaler。指定您要使用自定义类型对其进行编码。

MSDN有一整节专门讨论这个。

你最终会按照这些思路做一些事情:

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

然后将 MyCustomMarshaler 实现为 ICustomMarshaler .

关于C# 为 MarshalAs 属性类定义自定义 UnmanagedType,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7610069/

相关文章:

c# - 如何在 C# 中发送任意 FTP 命令

c# - Lambda 语法 : elements where a function has a certain value over a range of arguments

c# - 为什么仅在实现接口(interface)后才重写方法?

Java:字符串到字节数组的转换

binding - 编码时,为什么 JAXB 不为具有固定值的必需属性调用 getter 方法?

c# - 在托管代码中,我应该注意什么以保持良好的性能?

c# - C++/CLI clr :safe for C# COM Interop 中的包装器 C++

c# - 在 Unity3D 实例化的 UI 元素之间创建导航

.net - 如何将字符串数组转换为 .NET 中的 LPCWSTR 以传递给 Win32 API 函数?

c# - 如何将非托管内存数组复制到同一个非托管内存中