【问题标题】:c# endianness and structurec# 字节序和结构
【发布时间】:2018-07-18 13:56:52
【问题描述】:

我试图从微控制器获取一些数据包到 c# 程序:

我在两个地方都定义了一个结构。我计算 (sizeof(packet)-4bytes) 的 crc32 并将其放在 mydata_t.crc32 ...

struct mydata_t
{
    public byte cmd;
    public UInt32 param;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public Char[] str_buf;
    public UInt32 crc32;
}

    private byte[] getBytes(mydata_t str)
    {
        int size = Marshal.SizeOf(str);
        byte[] arr = new byte[size];

        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(str, ptr, true);
        Marshal.Copy(ptr, arr, 0, size);
        Marshal.FreeHGlobal(ptr);
        return arr;
    }
    private mydata_t fromBytes(byte[] arr)
    {
        mydata_t str = new mydata_t();
        str.str_buf = new char[10];
        int size = Marshal.SizeOf(str);
        IntPtr ptr = Marshal.AllocHGlobal(size);

        Marshal.Copy(arr, 0, ptr, size);

        str = (mydata_t)Marshal.PtrToStructure(ptr, str.GetType());
        Marshal.FreeHGlobal(ptr);

        return str;
    }

public static UInt32 xcrc32(byte[] buf, int len)
{
    UInt32 crc = DefaultSeed;
    UInt32 counter = 0;
    while (len-- > 0)
    {
        crc = (crc << 8) ^ defaultTable[((crc >> 24) ^ buf[counter]) & 255];
        counter++;
    }
    return crc;
}

我的 CRC 函数需要字节和长度..所以当我收到数据时..“以字节为单位”我使用 (private mydata_t fromBytes(byte[] arr)) 将它们转换为结构

问题: 当我从结构转换为字节数组时,计算 CRC 是错误的“我相信这是因为 c# 中数据类型的字节序?我该如何解决这个问题?

这是我从微控制器发送的内容:

    mydata_t datablockTX;
    datablockTX.cmd = 2;
    datablockTX.param = 0x98765432;
    memcpy(datablockTX.str_buf,"hellohell",10);
    datablockTX.crc32 = xcrc32((char*) &datablockTX,sizeof(datablockTX) - sizeof(uint32_t)); 
    usb_write_buf((uint8_t*) &datablockTX,sizeof(datablockTX));

这是我收到并打印出来的:

Data Received:
    CMD: 2
    param: 2557891634
    str: hellohell
    crc: 658480750

然后是问题

public bool ValidateCRC()
{
    bool myvalidate;
    UInt32 mycrc_val;
    byte[] mybytes = getBytes(myblock);
    mycrc_val = Crc32.Crc32Algorithm.xcrc32(mybytes, mybytes.Length- sizeof(UInt32));
    //mycrc_val = Crc32.Crc32Algorithm.xcrc32(mybytes, 1);
    myvalidate = (mycrc_val == myblock.crc32);
    Console.WriteLine("c#:" + mycrc_val + " - MCU:" + myblock.crc32 + " - bool:" + myvalidate);
    return myvalidate;
}

这是它在控制台中打印的内容: c#:667986744 - SAM:658480750 - bool:False


我在 MCU 中试过这个:

        mydata_t datablockTX;
        datablockTX.cmd = 2;
        datablockTX.param = 0x98765432;
        memcpy(datablockTX.str_buf,"hellohello",10);
        //datablockTX.crc32 = xcrc32((char*) &datablockTX,sizeof(datablockTX) - sizeof(uint32_t)); 
        datablockTX.crc32 = xcrc32((char*) &datablockTX, 5); 
        usb_write_buf((uint8_t*) &datablockTX,sizeof(datablockTX));

这是我收到的:

CMD:2

参数:2557891634

str: 你好你好

crc: 1993296691

在 C# 中:

            byte[] mybytes = getBytes(myblock);
        //mycrc_val = Crc32.Crc32Algorithm.xcrc32(mybytes, mybytes.Length- sizeof(UInt32));
        mycrc_val = Crc32.Crc32Algorithm.xcrc32(mybytes, 5);
        myvalidate = (mycrc_val == myblock.crc32);
        Console.WriteLine("c#:" + mycrc_val + " - MCU:" + myblock.crc32 + " - bool:" + myvalidate);

控制台: c#:146416248 - MCU:1993296691 - bool:False

【问题讨论】:

  • 问题甚至可能在这里:public Char[] str_buf;... 除非您的微控制器使用 UTF-16 字符 :-) 可能它应该是 public byte[] str_buf。请注意,有各种 CRC32 算法...我希望您从一些代码手册中获取代码。是的,字节序可能是个问题。
  • 我确实将它转换为字节仍然相同,实际上我正在打印它.. 准确接收我作为文本发送的内容,所以我不认为这与 char 编码有关吗?
  • 谁知道?我们对您的微控制器一无所知。
  • 我正在接收正确的数据,只有当我从结构中的字节数组中计算 c# 中的 CRC 时才会得到正确的值。我确实使用定义的一些字节数组测试了 crc 函数由我在 mcu 和 c# 中得到相同的结果,所以它不在 crc 函数中“两个平台中的相同函数”我认为它与“c 编译器的结构填充”有关?嗯,但我不这么认为,因为我正确接收了值..
  • 不是字节序问题,也会影响param字段值,是正确的。所以 xcrc32() 是错误的,在这里没有希望得到帮助。考虑一下捷径,这个数据是通过 USB 发送的,它本身已经添加了 CRC 校验。所以不需要再次检查。

标签: c# endianness byte-shifting


【解决方案1】:

改变

public static UInt32 xcrc32(byte[] buf, int len)
{
    UInt32 crc = DefaultSeed;

    UInt32 crc = 0xff1fff1f;

您使用的DefaultSeed 错误。 (如果你想知道,我强行使用它......尝试了所有可能的 40 亿个种子)。适用于您提供的两个 crc。

【讨论】:

  • 你好,默认种子在c#和c中定义:uint32_t crc = 0xffffffffu;公共常量 UInt32 DefaultSeed = 0xffffffffu;
  • 你是对的......为什么?现在 c# 中的种子与 c 不同! ..
  • @Hasanalattar 你发现问题所在了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-16
  • 2016-02-01
  • 1970-01-01
  • 2010-09-24
  • 1970-01-01
相关资源
最近更新 更多