首页 > 解决方案 > C++ 中的结构体大小 & 转换为 C#

问题描述

我在从 Arduino 到 Unity 工作时遇到问题;本质上,我正在 C++ (Arduino) 中构建一个有效负载结构,并使用以下串行协议将其发送到 PC:

1 字节 - 标头

1 字节 - 有效载荷大小

X 字节 - 有效载荷

1 字节 - 校验和 (LRC)

有效载荷如下所示:

struct SamplePayload {
    double A;
    double B;
    double C;
    double D;
} payload;

当我 sizeof(payload) 得到 16 个字节时,当我相信 double 是 8 字节数据类型时;如果我添加另一个双倍结构是 20 个字节,依此类推。我是不是误会了什么?这导致了问题,因为它随后被转换为字节数据流并在 C# 中接收时转换为结构,我不确定等效的数据类型是什么(转换为双精度值会给出错误的值)。Unity 中的串行协议还依赖于正确的有效负载大小来读取流。

这可能是一个简单的答案,但我在任何地方都找不到,非常感谢!

标签: c#c++unity3darduinotype-conversion

解决方案


如果您的应用程序对数字不敏感,则可以使用以下方法:

而不是在你的结构中使用双精度数(这不是严格标准化的,如评论中所述),你可以使用 two int32_t, aandb来表示一个重要的和一个指数,这样
a*2^b = original_double

所以你的结构看起来像这样:

    struct SamplePayload {
    int32_t A_sig;
    int32_t A_exp;
    //B,C...
} payload;

然后在接收方,您只需根据上面的公式乘以得到原始的双倍。

C 为您提供了一个简洁的函数frexp, 来简化事情。
但是由于我们将a和都存储b为整数,因此我们需要稍微修改结果以获得高精度。

具体来说,由于a保证在 0.5 和 1 之间,因此您需要乘以a2^30,然后再减去 30 b,以免溢出。

这是一个例子:

#include <stdio.h>      /* printf */
#include <math.h>       /* frexp */
#include <stdint.h>

int main ()
{
  double param, result;
  int32_t a,b;

  param = +235.0123123;
  result = frexp (param , &b);
  a=(result*(1<<30)) /*2^30*/; b-=30;
  printf ("%f = %d * 2^%d\n", param, a, b); //235.012312 = 985713081 * 2^-22                                                                                                                 

  return 0;
}

推荐阅读