Запись нескольких полей (структур) в fifo

Мне нужно написать следующую структуру в fifo:

struct msg_t {
   int length;
   char* msg;
};

Я выделяю структуру и char* внутри нее и пишу так: (допустим, msg — это имя переменной) write(fifo_fd, &msg, sizeof(msg_t));

Длина читается с другого конца просто отлично. Строка не... Как я могу написать эти два поля одной записью? Если нет, то хороши ли две отдельные записи?

Спасибо.


person dlvhdr    schedule 23.12.2013    source источник
comment
Для ясности включите некоторый код того, что вы пытаетесь сделать!   -  person rullof    schedule 23.12.2013


Ответы (2)


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

struct msg_t msg;
// Initialise msg
write( fifo_fd, &(msg.length), sizeof(int) );
write( fifo_fd, msg.msg, msg.length );
person Sodved    schedule 23.12.2013
comment
Спасибо .. Это то, о чем я думал, но я думал, что есть способ сделать это за одну запись. Думаю, это самый правильный способ :) - person dlvhdr; 23.12.2013
comment
@dlv Есть способы сделать это за одну запись, но для хранения данных требуется некоторая подготовительная работа. Честно говоря, это не проблема, если это все, что вы хотите сделать. Этот ответ сделает то, что вам нужно. (+1, кстати). - person WhozCraig; 23.12.2013

Рассматривали ли вы возможность использования элементов гибкого массива (также объясняется здесь)? См. это... Итак, объявите

struct msg_t {
    unsigned length;
    char msg[];
};

выделить его, например.

struct msg_t* make_msg(unsigned l) {
  // one extra byte for the terminating null char
  struct msg_t* m = malloc(sizeof(struct msg_t)+l+1; 
  if (!m) { perror("malloc m"); exit(EXIT_FAILURE); };
  memset(m, 0, sizeof(struct msg_t)+l+1);
  m->length = l;
  return m;
}

затем напишите это, например.

fwrite(m, sizeof(struct msg_t)+m->length+1, 1, fil);

или если вы используете write, выполните буферизацию самостоятельно (поскольку write может быть частичным!), например.

void write_msg(int fd, struct msg_t *m) {
   assert(m != NULL);
   char* b = m;
   unsigned siz = sizeof(struct msg_t)+m->length+1);
   while (siz>0) {
      int cnt=write (fd, b, siz);
      if (cnt<0) { perror("write"); exit(EXIT_FAILURE); };
      b += cnt;
      siz -= cnt;
   }
}
person Basile Starynkevitch    schedule 23.12.2013
comment
Есть ли причина, по которой вместо length используется unsigned, а size_t? - person alk; 23.12.2013