Как преобразовать 6 байт необработанных данных в тип long long?

data-type byte-order

Я пытаюсь решить несколько задач для конкурса, и у меня возникла проблема. Мне нужно реализовать функцию с 3 аргументами, например:

void foo(unsigned char* A, unsigned char* B, unsigned char* C);

И то, что приходит, это 6 байт данных. Мне нужно преобразовать эти 6 байт данных в целочисленные данные (возможно, long long). Проблема в том, что я не знаю, как отобразить байты в правильном порядке.

Я использую плату Arduino Uno.

Пожалуйста, помогите мне с этим.

, 👍0

Обсуждение

Каков правильный порядок шести байтов? И как они содержатся в массивах char из параметров функций?, @chrisl

@chrisl 0x123412341234 в {0x12,0x34,0x12,0x34,0x12,0x34}, @qqq1ppp

Я не совсем уверен, что именно вы хотите сделать. Насколько я понимаю, вы получаете 3 массива символов с 2 байтами в каждом в правильном порядке в качестве параметров в свою функцию, а затем вы хотите объявить long long и заполнить байтами из массивов эту переменную. Это правильно?, @chrisl

@chrisl нет. каждый из параметров вводит 6 байт данных. и я хочу преобразовать их так, как я сказал/, @qqq1ppp


3 ответа


Лучший ответ:

3

Вся хитрость в том, чтобы использовать тип данных union и получить полный контроль над отображением. Вопрос представления данных и порядка байтов теперь под вашим контролем:

uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
  union {
    uint64_t X;
    struct {
      uint8_t A[2];
      uint8_t B[2];
      uint8_t C[2];
      uint8_t D[2];
    };
  } map;
#if defined(MSB_ORDER)
  for (int i = 0, j = 1; i < 2; i++, j--) {
    map.A[i] = 0;
    map.B[i] = C[j];
    map.C[i] = B[j];
    map.D[i] = A[j];
  }
#else
  for (int i = 0; i < 2; i++) {
    map.A[i] = A[i];
    map.B[i] = B[i];
    map.C[i] = C[i];
    map.D[i] = 0;
  }
#endif
  return map.X;
}

void setup()
{
  Serial.begin(9600);
  while (!Serial);
  uint8_t a[] = { 0x12, 0x34 };
  uint8_t b[] = { 0x56, 0x78 };
  uint8_t c[] = { 0x9a, 0xbc };
  uint64_t res = foo(a, b, c);
  Serial.print((uint32_t) (res >> 32), HEX);
  Serial.print((uint32_t) res, HEX);
}

void loop()
{
}

Ура!

,

0

При передаче данных в функции вы делаете это...

foo(a,b,c);

Затем вы извлекаете переменные или данные, переданные в функцию, например...

void foo(unsigned char* A, unsigned char* B, unsigned char* C) {
    A = whatever;
    B = whatever;
    C = whatever;
}
,

ух ты. Я не такой уж и нуб ;; Я хочу преобразовать необработанные 6-байтовые данные в переменную типа «long long». memcpy не будет работать так, как мне нужно, из-за правил порядка байтов., @qqq1ppp

Ну, ваша функция была написана неправильно. Так каждый VAR или CHAR тогда составляет 2 байта?, @Brian Moreau


1
uint64_t foo(uint8_t* A, uint8_t* B, uint8_t* C)
{
    uint64_t aux = 0;
    aux = A[0];
    aux <<= 8;
    aux |= A[1];
    aux <<= 8;
    aux |= B[0];
    aux <<= 8;
    aux |= B[1];
    aux <<= 8;
    aux |= C[0];
    aux <<= 8;
    aux |= C[1];
    return aux;
}

следующий пример кода:

  uint8_t a[] = { 0x12, 0x34 };
  uint8_t b[] = { 0x56, 0x78 };
  uint8_t c[] = { 0x9a, 0xbc };

  uint64_t result = foo(a, b, c);

  std::cout << std::hex << result;

возвращает 123456789abc, попробуйте код здесь, за исключением части std::out, тот же код будет работать на arduino без каких-либо проблем

,