C e Erlang: exemplo do Erlang Port
Disclaimer: O autor da pergunta tem um conhecimento médio de Erlang e um conhecimento básico de C.
Eu estou lendo oGuia do Usuário do Tutorial de Interoperabilidade agora. Eu tenho compilado com sucesso ocomplex.c
exemplo e funciona com o Porto de Erlang sem problemas.
No entanto, gostaria de entender como o código C atual funciona. Eu o entendo em geral: no exemplo, ele lê 2 bytes da entrada padrão e verifica o primeiro byte. Dependendo do primeiro byte, ele tambémfoo
oubar
função. Este é o limite da minha compreensão disso agora.
Então, se levarmos os doiserl_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);
}
eport.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);
}
}
O que cada função realmente faz lá? Qual finalidadeli, len, i, wrote, got
variáveis realmente servem?
Mais algumas pequenas perguntas:
Por que as funções não têm nenhum tipo de retorno,void
s?Quando a porta Erlang envia dados para C, o primeiro byte determina uma função a ser chamada. Se o byte contiver o decimal 1, entãofoo()
é chamado, se o byte contém o decimal 2, entãobar()
é chamado. Se não for alterado, este protocolo pode ser usado para chamar até 255 diferentes funções C com apenas 1 parâmetro cada. Isso esta certo?"Adicionar o indicador de comprimento será feito automaticamente pela porta Erlang, mas deve ser feito explicitamente no programa C externo". O que isso significa? Em qual linha de código é feito?No Tutorial: "Por padrão, o programa C deve ler a partir da entrada padrão (descritor de arquivo 0) e gravar na saída padrão (descritor de arquivo 1)." Então: "Note que stdin e stdout são para entrada / saída em buffer e não devem ser usados para a comunicação com Erlang!" Qual é o problema aqui?porquebuf
é inicializado para[100]
?