2017-03-28 1 views
-1

Ocamlトップレベル(*シェルに 'ocaml'を入力するとインタラクティブインタプリタ)に* .mlファイルをロードしてから、MATLABプロセスから命令を送信する必要があります。get命令の結果を元に戻し、別の命令を送り返します。インタラクティブなocamlインタープリタと別のプロセスとの通信

私はこのCプログラムを作成しました。親プロセスは、名前付きパイプからMatlabの命令を取得し、子プロセス(ocamlを実行中)に送信し、レスポンスを戻してMatlabに送信します。

しかし、バグのいくつかの種類があります:私は命令を送信するとき、私は、いくつかの奇妙な文字を取り戻す、私は別の命令を送信し、その後、私は最初の命令の応答を受け取るには...

(I」のdidnの

:tは

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 

int main(void) { 

    // Parent -> Child 
    int pipe_in[2]; 
    // Child -> parent 
    int pipe_out[2]; 

    /* 
     pipe[0] = output 
     pipe[1] = input 
    */ 

    pipe(pipe_in); 
    pipe(pipe_out); 

    pid_t pid; 
    if ((pid = fork()) == 0) { 
     // CHILD SIDE 

     close(pipe_in[1]); 
     close(pipe_out[0]); 

     dup2(pipe_in[0], STDIN_FILENO);  
     dup2(pipe_out[1], STDOUT_FILENO); 
     dup2(pipe_out[1], STDERR_FILENO); 

     close(pipe_in[0]); 
     close(pipe_out[1]); 

     char *args[] = {"ocaml", NULL}; 
     execvp("ocaml", args); 

     printf("FAIL\n"); 

     exit(EXIT_FAILURE);  

    } else { 
     // PARENT SIDE 

     printf("[*] PID : %d\n", (int) pid); 

     close(pipe_in[0]); 
     close(pipe_out[1]); 

     char cmd[1024]; 
     char feedback[1024]; 
     ssize_t cmd_read; 
     ssize_t feedback_read = sizeof(feedback); 

     while (1) { 

      // Get the instruction from Matlab. 
      printf("[>] "); 
      int fifo_in = open("/tmp/pipe_in", O_RDONLY); 
      cmd_read = read(fifo_in, cmd, sizeof(cmd)); 
      close(fifo_in);   
      printf("%s\n", cmd); 

      // Send the instruction to the ocaml interpreter. 
      write(pipe_in[1], cmd, cmd_read); 

      // Read the response of the ocaml interpreter. 
      while (feedback_read == sizeof(feedback)) { 
       feedback_read = read(pipe_out[0], feedback, sizeof(feedback)); 
       printf("[-] %d\n", (int) feedback_read); 
      } 

      printf("[<] %s\n", feedback); 

      // Send to Matlab the response. 
      int fifo_out = open("/tmp/pipe_out", O_WRONLY); 
      write(fifo_out, feedback, feedback_read); 
      close(fifo_out); 

      cmd_read = 0; 
      feedback_read = sizeof(feedback); 

     } 

     close(pipe_in[1]); 
     close(pipe_out[0]); 
    } 
} 

は私が1つのシェルでのprogrammを実行gcc -Wall -std=c99 -o tphr tphr.c と、別のコードをコンパイル)以下のテキストを持つことにperror()テストをコピー

> printf 'let x = 10;;\n' > /tmp/pipe_in 

> cat /tmp/pipe_out 
OCaml version 4.03.0 

# % 

> printf 'let y = 5;;\n' > /tmp/pipe_in 

> cat /tmp/pipe_out 
val x : int = 10 
# % 

結果を修正するにはどうすればよいですか?

答えて

0

の場合は、 "変な文字" で、あなたは、これはOCamlのトップレベルは、起動時に出力しますものですので、単純である

OCamlのバージョン4.03.0

を意味します。だから自分のプログラムが起動するときにこの行を読む必要があります。

#シンボル(プロンプト)を使用している場合は、ocaml -nopromtを実行してオフにすることができます。

+0

申し訳ありませんが、これは明確ではありませんでした。奇妙な文字で、ヘッダーやプロンプトについては言及していません。各 '%'文字は、 '^ [[A'、および他の見えないもののようなエスケープ文字に置き換わります。しかし、奇妙なキャラクターでさえ、なぜプログラムが最初の命令のすべての応答(ヘッダーとval x ...)を読み取ることができないのですか?中の状態は良くないのですか?子プロセスが決してパイプの側面を閉じることはないからです。 –

0

あなたは複数の理由のために、ここでインタラクティブなOCamlのトップレベルを実行する必要はありません:

  1. トップレベルユーザーのconfigfilesを解析し、別のモジュールをロードします。これは利用可能な値を変更し、動作を変更し、ユーザごとに異なる結果を得るようにします。
  2. トップレベルの出力は、それが困難

をMathWorks社のMATLAB権の返信を解析して返すようになっバージョン間で変更される可能性があり、あなたは、文字列をinterpreteするocamlのバイトコードからトップレベルを呼び出すことができることをご存知ですか?私は、Cコードをダンプし、ocamlバイトコードを書き込んでパイプから読み込み、コマンドを解釈して結果を返信することをお勧めします。

+0

私はメモリにファイルをロードし、ファイルをもう一度解釈せずに定義された関数と変数と対話するためのすべての命令を解釈する必要があります。私は関数を呼び出す必要があります、結果を得る、別の関数を呼び出す、別の結果を得る...私はあなたのテクニックでそれを行うことができると思いますか? –

+0

確かに。 Ocamlはファイルを開き、文字列に読み込んでインタプリタに渡すことができます。それはバイトコードです。ネイティブコードでは動作しません。ネイティブコードでは通話するインタプリタがないからです。 –