Я подозреваю, что вас окружает (каламбур): заполнение структуры
ПРЕДЛОЖЕНИЕ:
Считывание данных непосредственно с вашего устройства в локальный буфер. Создайте буфер как минимум до самого большого ожидаемого сообщения.
Считайте заголовок
Выполните ваш "mallo c" и наконец
Распакуйте данные из вашего буфера в вас
ОК: Вот что я бы предложил:
/*
* SAMPLE OUTPUT:
* sizeof(*my_msg)= 16
* header: 01 02 03 04 05 06 07 08
* data: 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14
*/
#include <stdio.h>
#include <stdint.h> // unit8_t
#include <stdlib.h> // malloc()
#include <string.h> // memcpy ()
typedef struct MyMessage {
uint8_t header[8]; // 8 bytes (you said) for header; message length unknown.
uint8_t* data; // Here, you're only allocating space for a pointer (e.g. 4 bytes)
} MyMessage_t;
MyMessage_t* FunctionThatIsNotWorking(uint8_t* rawBytes) {
// Let's assume rawBytes contains header + data
// Parse the header, determine message type, and determine message length
// ... TBD ...
// Allocate your struct
MyMessage_t* ret_msg = malloc(sizeof (struct MyMessage));
// Now allocate space for your *data* (let's assume this particular message has 12 bytes)
ret_msg->data = malloc(12);
// Copy your header (from rawBytes)
memcpy(&ret_msg->header, rawBytes, 8);
// Copy the data (starting on the ninth byte; assume the data is contiguous)
memcpy(ret_msg->data, &rawBytes[8], 12);
// Return the completed record
return ret_msg;
}
int main() {
int i;
// Create some dummy data
uint8_t raw_bytes[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
MyMessage_t* my_msg = FunctionThatIsNotWorking(raw_bytes);
printf ("sizeof(*my_msg)= %ld\n", sizeof(*my_msg));
printf ("header: ");
for (i=0; i<sizeof(my_msg->header); i++) {
printf("%02x ", my_msg->header[i]);
}
printf ("\ndata: ");
for (i=0; i<12; i++) {
printf("%02x ", my_msg->data[i]);
}
printf ("\n");
return 0;
}
Суть, которую я пытался сделать, заключается в том, что компоновка байтов, которую компилятор дает вашей структуре, НЕ обязательно того, что вы могли ожидать. В полях часто имеется «дополнительный интервал» для обеспечения выравнивания.
Если вы используете структуры на стороне отправки (при создании сообщения), компоновка данных в получателе не обязательно будет соответствовать компоновке в Отправитель.
Следовательно, вам обычно нужно явно «упаковывать» и «распаковывать» сообщения, которые вы отправляете туда и обратно между различными хостами / разными платформами.
Я думаю, что главное было подчеркнуть, что вы никогда не выделяли место для ваших данных. Это правда :) Надеюсь, что приведенный выше пример поможет.
Наконец, в большинстве случаев длина сообщения будет неизвестна, пока вы действительно не прочитаете заголовок. Мой пример также обрабатывает этот случай.
В случае, если вы хотите передать данные только вызывающей стороне (в моем примере копируются как заголовок, так и данные), вы, вероятно, захотите добавить поле "длина сообщения" в вашей структуре.
Всегда старайтесь использовать оператор "sizeof" вместо жесткого кодирования "magi c numbers". Следующая лучшая вещь - объявить константу (например, #define DATA_LENGTH 12
).
'Надеюсь, это поможет!
Еще один пример.
Допустим, вы знать данные вашего сообщения всегда будут ровно 12 байтов. и давайте все же предположим, что вы хотите, чтобы поле заголовка было 8 байтов. Вы можете сделать это:
...
typedef struct MyMessage {
uint8_t header[8]; // 8 bytes (you said) for header
uint8_t data[12]; // This allocates 12 bytes
} MyMessage_t;
...
MyMessage_t* FunctionThatIsNotWorking(uint8_t* rawBytes) {
// Let's assume rawBytes contains header + data
// Parse the header, determine message type, and determine message length
// ... TBD ...
// Allocate your struct
MyMessage_t* ret_msg = malloc(sizeof (*ret_msg));
// Copy directly from rawBytes
memcpy(ret_msg, rawBytes, sizeof (*ret_msg));
// Return the completed record
return ret_msg;
}