免責事項:質問の作成者は、アーランの平均的な知識と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にデータを送信するとき、最初のバイトが呼び出される関数を決定します。バイトが10進数の1を保持している場合は、
foo()
が呼び出され、バイトが10進数の2を保持している場合は、bar()
が呼び出されます。とにかく変更されていない場合は、このプロトコルを使用して、それぞれ1つのパラメーターのみで最大255の異なるC関数を呼び出すことができます。そうですか? - 「長さインジケーターの追加はErlangポートによって自動的に行われますが、外部Cプログラムで明示的に行う必要があります」。どういう意味ですか?コードのどの行で実行されますか?
- チュートリアルから:「デフォルトでは、Cプログラムは標準入力(ファイル記述子0)から読み取り、標準出力(ファイル記述子1)に書き込む必要があります。」次に、「stdinとstdoutはバッファリングされた入力/出力用であり、Erlangとの通信には使用しないでください!」ここでのキャッチは何ですか?
- なぜ
buf
に初期化されるの[100]
ですか?