简体   繁体   English

C ++中的结构大小和转换为C#

[英]Struct size in C++ & conversion to C#

I'm having an issue working from Arduino to Unity; 从Arduino到Unity,我遇到了问题; essentially I'm building a payload struct in C++ (Arduino) and sending it to a PC using the following serial protocol: 本质上,我在C ++(Arduino)中构建有效负载结构,并使用以下串行协议将其发送到PC:

1 byte - header 1个字节-标头

1 byte - payload size 1个字节-有效负载大小

X bytes - payload X字节-有效负载

1 byte - checksum (LRC) 1个字节-校验和(LRC)

The payload looks like so: 有效负载如下所示:

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

when I sizeof(payload) I get 16 bytes, when I believe a double is an 8 byte data type; 当我sizeof(payload)时,我得到16字节,当我相信double是8字节数据类型时; if I add another double the struct is 20 bytes and so on. 如果我再添加一个double,则该结构为20个字节,依此类推。 Am I misunderstanding something? 我误会了吗? This is causing issues as this is then converted to a byte data stream and cast as a struct on receipt in C#, and I'm not sure what the equivalent datatype would be (casting as a double gives wrong values). 这会引起问题,因为随后将其转换为字节数据流并在C#中在接收时强制转换为结构,而且我不确定等效的数据类型是什么(以double形式广播会给出错误的值)。 The serial protocol in Unity also relies on the correct payload size to read out the stream. Unity中的串行协议还依靠正确的有效负载大小来读取流。

It is probably a straightforward answer but I couldn't find it anywhere, many thanks! 这可能是一个简单的答案,但我在任何地方都找不到,非常感谢!

If your application is not numerically sensitive, you could use the following approach: 如果您的应用程序对数字不敏感,则可以使用以下方法:

Instead of using doubles within your struct (which aren't strictly standardized, as mentioned in the comments), you could use two int32_t , a and b for representing a significant and an exponent such that 您可以使用两个int32_tab来表示一个int32_t和一个指数,而不是在结构中使用双精度数(如注释中所述,严格将其标准化)。
a*2^b = original_double a * 2 ^ b = original_double

So your struct will look something like this: 因此,您的结构将如下所示:

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

Then on the receiving side, you will only have to multiply according to the formula above to get the original double. 然后,在接收端,您只需按照上述公式相乘即可得到原始的两倍。

C provides you with a neat function, frexp , to ease things up. C为您提供了一个简洁的函数frexp ,以简化操作。
But since we store both a and b as integers, we need to modify the results a bit in order to get high precision. 但是由于我们将ab都存储为整数,因此我们需要对结果进行一些修改才能获得较高的精度。

Specifically, since a is guaranteed to be between 0.5 and 1, you need to multiply a by 2^30, and subtract 30 from b in order not to overflow. 具体来说,由于保证a在0.5到1之间,因此您需要将a乘以2 ^ 30,然后从b中减去30以免溢出。

Here's an example: 这是一个例子:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM