Отправка и получение структуры в Contiki - Работа с указателями и структурами - PullRequest
0 голосов
/ 22 февраля 2019

В настоящее время я делаю простую программу, которая пытается отправить структуру по сети, используя contiki.У меня есть функция, которая вызывается при получении передачи, и функция, которая вызывается для передачи.

Структура определяется следующим образом:

 struct metadata {
    int values[5];
 };
 struct metadata packet;
 int max_val = 100;
 int min_val = 1;
 int random_val = random_rand();
 if(random_val < 0)
 {
   random_val *= -1;
 }

 int proposal_value = (random_val % max_val) + min_val;

 int index = node_id - 1;
 packet.values[index] = proposal_value;

Функция передачи:

static void trickle_tx(void *ptr, uint8_t suppress)
{
  uip_ipaddr_copy(&trickle_conn->ripaddr, &ipaddr);
  uip_udp_packet_send(trickle_conn, &packet, sizeof(packet));

  /* Restore to 'accept incoming from any IP' */
  uip_create_unspecified(&trickle_conn->ripaddr);

  leds_off(LEDS_RED);
}

следующий код предназначен для функции tcpip_handler, которая вызывается, когда пылинка получает передачу.

Насколько я знаю, я посылаю &packet, который является адресом памятимоя структура пакета.После получения я хочу данные в этой структуре, поэтому сначала нужно получить доступ к ячейке памяти.Поэтому я создаю переменную received_struct типа struct metadata следующим образом:
Первый подход :

   if(uip_newdata()) {
    struct metadata received_struct;
    received_struct = (struct metadata) *uip_appdata;
    int data[5];

    data = received_struct.values;
   }

Ошибка :

proposer.c:120:31: error: invalid use of void expression
proposer.c:123:10: error: incompatible types when assigning to type ‘int[5]’ from type ‘int *

ВТОРОЙ ПОДХОД :
Итак, отсюда я попробовал альтернативный подход, где я приводил полученный пакет к указателю метаданных.Затем я назначаю received_struct указателем на received_struct.На данный момент я считаю, что received_struct теперь находится в «нормальном» формате, не указатель и не адрес.Однако это также не работает.

 if(uip_newdata()) {
    struct metadata* received_struct_ptr;
    received_struct_ptr = (struct metadata*) uip_appdata;
    struct metadata received_struct;
    received_struct = *received_struct_ptr;
    int data[5];

    data = received_struct.values;
    }

ОШИБКА:

proposer.c: 125: 10: ошибка: несовместимые типы при назначении типу 'int [5]' из типа'int *'

APPROACH 3:
Для этого подхода я приводю входящие данные к указателю metdata, затем я получаю заданную структуру, указанную этими присвойте его data_struct и попытайтесь получить доступ к данным.

  if(uip_newdata()) {
    struct metadata* struct_pointer;
    struct_pointer = (struct metadata*) uip_appdata;
    struct metadata data_struct;
    data_struct = *struct_pointer;
    int data [5];

    data = &data_struct.values;

ОШИБКА :

proposer.c:125:10: error: incompatible types when assigning to type ‘int[5]’ from type ‘int (*)[5]’

Если честно, я действительно понятия не имеючто тут происходит.Я думал, что это будет так же просто, как взять указатель на адрес памяти, получить структуру и получить к ней доступ, но этого не происходит.Я думал, что понял, но, похоже, я не совсем понимаю указатели.

Буду признателен за любую помощь.

1 Ответ

0 голосов
/ 22 февраля 2019

Вы были на правильном пути со вторым подходом.

received_struct_ptr = (struct metadata*) uip_appdata;
struct metadata received_struct;
received_struct = *received_struct_ptr;
int data[5];

Вы привели указатель к правильному типу и присвоили полученные данные структуре.Но в языке C нет встроенной функции назначения каждого члена массива другому массиву, поэтому вам нужно сделать это вручную:

int i;
for(i=0; i<5; ++i)
{
    data[i] = received_struct.values[i];
}

Обратите внимание, что data isn 'на самом деле он более доступный или полезный, чем received_struct.values, и вы ввели в код другое число 5.Это может быть проблемой, если размер массива изменится в будущем.Таким образом, учитывая все вышесказанное, вам может быть лучше получить прямой доступ к этим данным (int final_value = received_struct.values[4];), а не делать копию.

...