Ответ 1
Этот ответ также отклонен (я не программист Erlang или C, я просто переживаю один и тот же материал)
Ваша начальная модель немного выключена. То, как работает код, - это чтение первых двух байтов из stdin
, предполагая, что это означает длину фактического сообщения, а затем чтение этого большего количества байтов из stdin
. В этом конкретном случае бывает, что фактическое сообщение всегда состоит из двух байтов (число, соответствующее функции и один целочисленный аргумент для передачи).
0 - a) read_exact
читает len
байты из stdin
, read_cmd
сначала использует read_exact
, чтобы определить, сколько байтов он должен прочитать (либо число, обозначенное первые два байта или ни один, если имеется меньше двух байтов), а затем читать это количество байтов. write_exact
записывает len
bytes в stdout
, write_cmd
использует write_exact
для вывода заголовка с длиной в два байта, за которым следует сообщение (надеюсь) соответствующей длины.
0 - b) Я думаю, что len
достаточно подробно рассмотрено выше. li
- это имя переменной, используемой для генерации этого двухбайтового заголовка для функции записи (я не могу выполнить шаг за шагом по операциям сдвига бит, но конечным результатом является то, что len
представлен в первые два байта отправлены). i
является промежуточной переменной, основной целью которой является обеспечение того, чтобы write
и read
не возвращали ошибку (если они это делают, этот код ошибки возвращается в результате read_exact
/write_exact
). wrote
и got
отслеживать, сколько байтов было записано/прочитано, причем контуры с конвейерами должны быть выше, чем len
.
1 - Я на самом деле не уверен. Версии, с которыми я работал, имеют тип int
, но в остальном идентичны. Я получил из главы 12 Программирование Erlang, а не ссылку, которую вы связываете.
2 - Это правильно, но точка протокола порта заключается в том, что вы можете изменить его для отправки разных аргументов (если вы отправляете произвольные аргументы, вероятно, было бы лучше всего просто используйте C Node, а не порты). Например, я изменил его тонко в недавнем фрагменте, так что он отправляет одну строку, так как у меня есть только одна функция, которую я хочу вызвать C, устраняя необходимость указания функции. Я должен также упомянуть, что если у вас есть система, которая должна вызывать более 255 различных операций, написанных на C, вы можете захотеть переосмыслить свою структуру (или просто перевести все девять и записать все это на C).
3 - Выполняется
read_cmd(byte *buf)
{
int len;
if (read_exact(buf, 2) != 2) // HERE
return(-1); // HERE
len = (buf[0] << 8) | buf[1]; // HERE
return read_exact(buf, len);
}
в функции read_cmd
и
write_cmd(byte *buf, int len)
{
byte li;
li = (len >> 8) & 0xff; // HERE
write_exact(&li, 1); // HERE
li = len & 0xff; // HERE
write_exact(&li, 1); // HERE
return write_exact(buf, len);
}
в функции write_cmd
. Я думаю, что объяснение приведено в 0 - a)
; что заголовок, который сообщает/узнает, как долго будет остальное сообщение (да, это означает, что это может быть только конечная длина, и эта длина должна быть выражена в двух байтах).
4 - Я не совсем уверен, почему это было бы уловкой здесь. Учиться разрабатывать?
5 - buf
является байтовым массивом и должен быть явно ограничен (для целей управления памятью, я думаю). Я читал "100
" здесь как "число, большее, чем максимальный размер сообщения, который мы планируем разместить". Фактическое число, выбранное, кажется произвольным, кажется, что что-либо 4 или выше, но я мог бы быть исправлен в этот момент.