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
:
<code>/* 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); } </code>
eport.c
:
<code>/* 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); } } </code>
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]
?