免责声明:该问题的作者对 Erlang 有一个平均的了解,对 C 有基本的了解。
我现在正在阅读互操作性教程用户指南。我已经成功编译了这个complex.c
例子,它可以与 Erlang Port 一起使用,没有任何问题。
但是,我想了解实际的 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 函数,每个函数只有 1 个参数。那正确吗? - “添加长度指示器将由 Erlang 端口自动完成,但必须在外部 C 程序中显式完成”。这意味着什么?它是在哪一行代码上完成的?
- 来自教程:“默认情况下,C 程序应从标准输入(文件描述符 0)读取并写入标准输出(文件描述符 1)。” 然后:“请注意,stdin 和 stdout 用于缓冲输入/输出,不应用于与 Erlang 的通信!” 这里有什么问题?
- 为什么
buf
初始化为[100]
?