В примере файл "usb.c" расположен по адресу:
http://www.linux-usb.org/gadget/usb.c
Внутри функции init_device
меня возникли проблемы с пониманием того, почему автор хотел преобразовать буфер в указатель. Ниже приведен сокращенный фрагмент кода:
char buf [4096], *cp = &buf [0]; int fd; int status = 0; char *DEVNAME = "musb-hdrc"; if (status < 0) { fprintf (stderr, "?? don't recognize/dev/gadget %s device\n", "iso"); return status; } fd = open (DEVNAME, O_RDWR); if (fd < 0) { perror (DEVNAME); return -errno; } *(__u32 *)cp = 0;/* tag for this format */cp += 4;/* write configs */cp = build_config (cp, hs_eps);/* and device descriptor at the end */memcpy (cp, &device_desc, sizeof device_desc); cp += sizeof device_desc; status = write (fd, &buf [0], cp - &buf [0]);
Wwhy автор хотел создать *cp
? не писал бы на адрес первого элемента массива, просто записывающего в массив? Кажется, что, когда он действительно использует то, что он написал в *cp
он просто заканчивает использование буфера в любом случае...
Кроме того, что именно он делает с:
*(__u32 *)cp = 0;
Это какой-то указатель на предмет указателя? Зачем добавить 4 к нему, а потом просто написать над ним?
Я чувствую, что я понимаю большую часть происходящего в этой процедуре, но пара вещей оставила меня озадаченным...
Автор создает cp
чтобы иметь указатель на массив. Затем они могут перемещать этот указатель с помощью cp += 4;
(мы увидим, почему шаги в 4 раза в секунду) и делайте что-то в этом новом месте.
*(__u32 *)cp = 0;
сначала накладывает указатель на тип __u32*
, который я могу только предположить, является указателем на 4-байтовое целое без знака. Затем они разыгрывают этот указатель и записывают значение 0 в объект, на который он указывает. Помните, что буфер состоит из char
s, размер которых равен 1 байту, а указатель cp
- char*
. Они набрасывают указатель на __u32*
чтобы они могли записывать в буфер 4 байта за раз. Поэтому, когда cp
указывает на первый элемент в буфере, они заканчивают установку первых 4 байтов буфера на 0. Вот почему они перемещают указатель вдоль 4 элементов, так что они могут справиться со всем после первых 4 байтов.
Это означает "лить cp
в __u32 *
, затем разглядеть его (внешний *
) и назначить 0
Это делается так, чтобы было __u32
правильное количество байтов (4 байта, предполагая, что __u32
- 32-разрядный тип).