Отказ от ответственности: автор вопроса имеет средние знания Erlang и базовые знания C.
Сейчас я читаю Учебное руководство пользователя по взаимодействию. Я успешно скомпилировал пример complex.c
, и он без проблем работает с портом Erlang.
Однако я хотел бы понять, как работает реальный код C. Я так понимаю в общем: в примере читает 2 байта из стандартного ввода и проверяет первый байт. В зависимости от первого байта вызывается функция foo
или bar
. Это предел моего понимания этого сейчас.
Итак, если мы возьмем оба erl_comm.c
:
/* erl_comm.c */
typedef unsigned char byte;
read_cmd(byte *buf)
{
int len;
if (read_exact(buf, 2) != 2)
return(-1);
len = (buf[0] << 8) | buf[1];
return read_exact(buf, len);
}
write_cmd(byte *buf, int len)
{
byte li;
li = (len >> 8) & 0xff;
write_exact(&li, 1);
li = len & 0xff;
write_exact(&li, 1);
return write_exact(buf, len);
}
read_exact(byte *buf, int len)
{
int i, got=0;
do {
if ((i = read(0, buf+got, len-got)) <= 0)
return(i);
got += i;
} while (got<len);
return(len);
}
write_exact(byte *buf, int len)
{
int i, wrote = 0;
do {
if ((i = write(1, buf+wrote, len-wrote)) <= 0)
return (i);
wrote += i;
} while (wrote<len);
return (len);
}
и port.c
:
/* port.c */
typedef unsigned char byte;
int main() {
int fn, arg, res;
byte buf[100];
while (read_cmd(buf) > 0) {
fn = buf[0];
arg = buf[1];
if (fn == 1) {
res = foo(arg);
} else if (fn == 2) {
res = bar(arg);
}
buf[0] = res;
write_cmd(buf, 1);
}
}
Что на самом деле делает каждая функция? Какой цели на самом деле служат li, len, i, wrote, got
переменные?
Еще несколько небольших вопросов:
- Почему у функций нет возвращаемых типов, даже
void
s? - Когда порт Erlang отправляет данные на C, первый байт определяет вызываемую функцию. Если байт содержит десятичную 1, то вызывается
foo()
, если байт содержит десятичную 2, то вызываетсяbar()
. Если ничего не изменить, этот протокол можно использовать для вызова до 255 различных функций C только с одним параметром в каждой. Это правильно? - «Добавление индикатора длины будет выполнено автоматически портом Erlang, но это должно быть сделано явно во внешней программе C». Что это значит? В какой строке кода это делается?
- Из учебника: «По умолчанию программа C должна читать со стандартного ввода (дескриптор файла 0) и записывать на стандартный вывод (дескриптор файла 1)». Затем: «Обратите внимание, что stdin и stdout предназначены для буферизованного ввода/вывода и не должны использоваться для связи с Erlang!» В чем тут подвох?
- почему
buf
инициализируется[100]
?