Размер структуры в C ++ и преобразование в C # - PullRequest
0 голосов
/ 31 мая 2018

У меня проблема с работой из Arduino в Unity;по сути, я создаю структуру полезной нагрузки в C ++ (Arduino) и отправляю ее на ПК, используя следующий последовательный протокол:

1 байт - заголовок

1 байт - размер полезной нагрузки

X байт - полезная нагрузка

1 байт - контрольная сумма (LRC)

Полезная нагрузка выглядит так:

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

когда я sizeof (полезная нагрузка) я получаю 16 байтовкогда я считаю, что тип данных double - это 8-байтовый тип данных;если я добавлю еще один двойной, структура будет 20 байтов и так далее.Я что-то неправильно понимаю?Это вызывает проблемы, так как это затем преобразуется в поток байтовых данных и приводится как структура при получении в C #, и я не уверен, каким будет эквивалентный тип данных (приведение к двойному типу дает неправильные значения).Последовательный протокол в Unity также полагается на правильный размер полезной нагрузки для считывания потока.

Возможно, это простой ответ, но я нигде не смог его найти, большое спасибо!

1 Ответ

0 голосов
/ 31 мая 2018

Если ваше приложение не чувствительно к числовому значению, вы можете использовать следующий подход:

Вместо использования двойников в вашей структуре (которые не строго стандартизированы, как указано в комментариях), вы можете использовать дваint32_t, a и b для представления значащего и показателя степени, такого как
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, вам необходимо умножить a на 2 ^ 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;
}
...