C программирование структуры передал в литом виде для обугливания *?

У меня есть немного проблемы в сценарии где:

while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf)) == sizeof(dirbuf)) { ... }

где dirbuf:

struct direct dirbuf { 
    ino_t d_ino; char d_name[DIRSIZ]; 
};  

Как C знает для чтения в данных условно в нашу структуру? С чтением () Как, выравнивание нашего dirbuf соответствует отлично как символьный массив? так как чтение признает, что пустота * для ее второго аргумента, передавая структуру как бросок для обугливания * имеет очень мало смысла мне, как это обслуживает другие членские элементы правильно?

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

Спасибо.

5
задан wakeup 1 March 2010 в 23:31
поделиться

3 ответа

Он не читает и не выравнивает поля в структуре должным образом. Он просто берет общий размер структуры (из sizeof ) и начальный адрес (из & dirbuf ) и считывает в эту память без учета объявления структуры.

Предполагается, что все, что было в файле, было уже правильно выровнено, чтобы соответствовать структуре.

Приведение (char *) используется только для остановки компилятора. (void *) подойдет так же. Или вообще без приведения, поскольку компилятор преобразует тип указателя в void * без приведения.

3
ответ дан 14 December 2019 в 01:06
поделиться

Это должно быть дань устаревшим версиям языка C, в которых не было типа void * , а вместо них использовался char * . Если вы используете неархаичный компилятор и параметр действительно равен void * , нет необходимости приводить что-либо к char * (и нет необходимости приводить что-либо к void * либо)

read(dp->fd, &dirbuf, sizeof(dirbuf)) 

И C не знает, и ему не нужно знать, как считывать данные в вашу конкретную структуру. Когда вы делаете что-то подобное, двоичные данные из файла вслепую считываются в необработанную память, занимаемую вашим объектом dirbuf . Если макет этих двоичных данных правильный (например, если файл был создан путем записи той же структуры таким же образом), тогда все будет правильно выровнено и все автоматически встанет на свои места.

Обратите внимание: если вы не работаете с чем-то, на что распространяется очень строгая спецификация, такие простые методы двоичной записи / чтения можно использовать только в одном сеансе одной и той же программы или, возможно, между разными сеансами одной и той же версии. программы на той же платформе. Как только вы начнете иметь дело с разными платформами и / или разными версиями кода на одной платформе, все может легко развалиться, как только изменится необработанная структура памяти данных.

0
ответ дан 14 December 2019 в 01:06
поделиться

Hysterical Raisens

Приведение буферов к char * - это устаревший шаблон кода, который часто встречается. Он использовался так часто, что его все еще набирают сегодня, спустя долгое время после того, как в нем перестала быть необходимость.

В какой-то момент не было типа void , поэтому API вроде read (2) объявлял бы параметр буфера как char * , и все вызывающие преобразовать свои данные в char * .

Но читать (2) было пустотой * долгое, долгое время. Прошло столько времени, когда на месте вызова была необходимость иметь какую-либо гипсовую повязку.

Однако старый код все еще существует, люди все еще читают его, а затем увековечивают шаблон проектирования.

Это не вредит.

Что касается непрерывных данных, происходит одно из двух. Либо структура данных и тип предназначены для плотного размещения на большинстве или всех вероятных машинах, либо аналогичный оператор использовался для записи данных в первую очередь, поэтому байты заполнения не имеют значения, если файл данных не должен быть перемещен между разрозненными архитектурами.

6
ответ дан 14 December 2019 в 01:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: