【问题标题】:8 byte array back to long (C# to c++)8 字节数组回长(C# 到 C++)
【发布时间】:2014-09-26 19:09:09
【问题描述】:

我正在使用 C# 将 long 转换为 8 槽字节数组

Byte[] Data = BitConverter.GetBytes(data.LongLength);

例如,如果data.LongLenght 是 172085,我得到以下数组 { 53,160,2,0,0,0,0,0 } 但是在我将它发送到我的 c++ 服务器之后,我想再次让它变得很长。

我试过了,但没有成功……

long fileLenght = 0;
for( int i=0;i < 8; ++i)
    fileLenght = (fileLenght << 8) + Data[i];

【问题讨论】:

  • 它是小端存储的,你必须向后迭代。请注意,C++ long 与 C# long 不同,您需要 long long。那种棘手的细节使得通过网络发送二进制数据是个好主意。
  • @HansPassant 所说的。您应该定义一个逐字节的协议,以便对等方始终可以重新组装您的数据,无论需要语言/版本/接收它的什么,(并且也检测消息边界 - 您的 8 字节消息可能不会在一个接收中到达打电话)。

标签: c# c++ bitconverter


【解决方案1】:

每当您通过网络发送数据时,您必须注意endianness

在您的情况下,从字节数组重新创建 long 的正确方法似乎是从右到左重建它:

long fileLength = 0;
for( int i=7; i >= 0; i--)
    fileLength = (fileLength << 8) + Data[i];

但情况并非总是如此。根据端点的硬件和操作系统,以及您使用的网络传输协议,您的数据可能以 big-endian 或 little-endian 格式传入,而接收端可能是 little-endian 或 big-endian。

【讨论】:

  • '当你通过网络发送数据时,你必须注意字节顺序' - 不是真的,不。您必须考虑一个合适的协议,以确保您的数据可以被正确解释。
  • @MartinJames - 我认为我们在谈论同样的事情 - 通过选择一个可以帮助您处理字节序的协议,您牢记(或至少承认它)。无论哪种方式,重要的是要知道并非所有系统和媒介都以相同的方式代表多字节值并相应地设定您的期望(我的 2c)
【解决方案2】:

来自documentation

GetBytes 方法返回的数组中的字节顺序取决于计算机体系结构是小端还是大端。

看起来在您的硬件上,数组首先发送其最低有效字节。因此,您应该从数组的末尾开始循环:

int64_t fileLenth = 0;
for( int i=7;i >= 0; --i)
    fileLenght = (fileLenght << 8) + Data[i];

Demo.(打印 172085)

为了更好地与 C# 兼容,您应该使用system-independent 64-bit integral type 而不是long,即int64_t

【讨论】:

    【解决方案3】:

    如果两端的字节顺序相同(C# 总是 little-endian,可能你的 C++ 也是):

    long long fileLength;
    memcpy(&fileLength, Data, 8);
    

    优化编译器几乎肯定会将其转换为单个 64 位移动,所以不要担心它看起来像一个昂贵的函数调用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 2013-01-16
      • 2012-11-12
      • 2013-12-24
      • 2013-10-07
      • 1970-01-01
      • 2011-07-31
      相关资源
      最近更新 更多