c# - 有没有一种通用的方法可以将结构写入 Big Endian 格式的字节?

标签 c# generics struct endianness cpu-architecture

我发现了问题 such as this one ,这已经接近解决我的困境。但是,我还没有找到一种干净的方法来以通用的方式解决这个问题。

我有一个项目有很多将用于二进制数据传输的结构。此数据需要是 Big Endian,当然,大多数 .Net 架构都是 Little Endian。这意味着当我将我的结构转换为字节时,我的值的字节顺序被颠倒了。

是否有一种相当直接的方法来强制我的结构包含 Big Endian 格式的数据,或者是否有一种方法可以将这些结构一般写入输出 Big Endian 数据的字节数组(以及字节数组到结构)?

这是我已经完成的一些示例代码。

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct StructType_1
{
    short shortVal;
    ulong ulongVal;
    int intVal;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public unsafe struct StructType_2
{
    long longVal_1;
    long longVal_2;
    long longVal;
    int intVal;
}

...

public static class StructHelper
{
    //How can I change the following methods so that the struct data 
    //is converted to and from BigEndian data?
    public static byte[] StructToByteArray<T>(T structVal) where T : struct
    {
        int size = Marshal.SizeOf(structVal);
        byte[] arr = new byte[size];
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(structVal, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
        return arr;
    }

    public static T StructFromByteArray<T>(byte[] bytes) where T : struct
    {
        int sz = Marshal.SizeOf(typeof(T));
        IntPtr buff = Marshal.AllocHGlobal(sz);
        Marshal.Copy(bytes, 0, buff, sz);
        T ret = (T)Marshal.PtrToStructure(buff, typeof(T));
        Marshal.FreeHGlobal(buff);
        return ret;
    }
}

最佳答案

如果您不介意将每个字段读写到流中(这可能会影响性能),您可以使用 Jon Skeet 的 EndianBinaryWriter:https://stackoverflow.com/a/1540269/106159

代码看起来像这样:

public unsafe struct StructType_2
{
    long longVal_1;
    long longVal_2;
    long longVal;
    int intVal;
}

using (MemoryStream memory = new MemoryStream())
{
    using (EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Big, stream))
    {
        writer.Write(longVal_1);
        writer.Write(longVal_2);
        writer.Write(longVal);
        writer.Write(intVal);
    }

    byte[] buffer = memory.ToArray();

    // Use buffer
}

您可以使用 EndianBinaryReader 获取相反方向的数据。

这当然有两个相当大的缺点:

  • 正在繁琐地编写代码来读写每个字段。
  • 根据性能要求,这样做可能会太慢。

另请查看此类似问题的答案:Marshalling a big-endian byte collection into a struct in order to pull out values

关于c# - 有没有一种通用的方法可以将结构写入 Big Endian 格式的字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25808429/

相关文章:

c# - HtmlAgilityPack 和身份验证

c# - 删除所有现有的 excel 图表系列

java - 具有循环泛型依赖项的泛型类型的编译错误

c - 海湾合作委员会错误 : string length too great (C11 type-generics)

c++ - 是否应该在 memset 之前对结构进行类型转换

C:指向结构内部结构元素的指针

c# - 如何在第一个循环 C# 后停止 PictureBox GIF 动画?

c# - 在 C# 中对字符串数组进行插入排序

java - 通用 map 打印功能

c++ - 是否可以有一个 "auto"成员变量?