PHPとC言語の連携
C言語で作成したプログラムをPHPから呼び出す必要に迫られたので、やり方をメモしておきます。
幾つかの方法がありますが、最も簡単なのは exec 等のプログラム実行関数を用いる方法です。
* プログラム実行関数 >> http://www.php.net/manual/ja/ref.exec.php
しかしexecだと、C言語側にデータを引き渡したり、C言語側からデータを戻したりするのが簡単にはできません。
何とかデータを受け渡しする方法が無いものかと探したところ、proc_open という関数がありました。
* proc_open >> http://www.php.net/manual/ja/function.proc-open.php
以下に試してみます。ほとんどマニュアルにあったサンプルと一緒です。
・proc_open.php
<?php$descriptorspec = array(
0 => array("pipe", "r"), // stdin は、子プロセスが読み込むパイプです。
1 => array("pipe", "w"), // stdout は、子プロセスが書き込むパイプです。
2 => array("file", "/tmp/error-output.txt", "a") // はファイルで、そこに書き込みます。
);// $cwd = '/my/current/directory';
// $env = array('some_option' => 'aeiou');// C言語で作成した実行プログラム.
$a_exe = '/full/path/to/a.exe'; // フルパスで書かないとダメみたいだ.$process = proc_open($a_exe, $descriptorspec, $pipes); // , $cwd, $env);
if (is_resource($process)) {
// $pipes はこの時点で次のような形を取っています。
// 0 => 子プロセスの stdin に繋がれた書き込み可能なハンドル
// 1 => 子プロセスの stdout に繋がれた読み込み可能なハンドル
// すべてのエラー出力は /tmp/error-output.txt に書き込みされます。// 以下にC言語側への入力を行う.
fwrite($pipes[0], "いっくよー\n");
fwrite($pipes[0], "ファイヤー!\n");
fwrite($pipes[0], "ばよえ〜ん!!\n");
fwrite($pipes[0], "\n"); // END mark.
fclose($pipes[0]);// ここでC言語側からの返り値を取得する.
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);// デッドロックを避けるため、proc_close を呼ぶ前に
// すべてのパイプを閉じることが重要です。
$return_value = proc_close($process);echo "command returned $return_value\n";
}?>
上のPHPから呼び出される、テスト用の実行プログラムをC言語にて作成します。
・proc_open_test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_LINE 1024
int main(){
char buf[ MAX_LINE ];
while(1){
fgets( buf, sizeof(buf), stdin );
buf[ strlen(buf) - 1 ] = '\0'; // 改行コードを消す
fflush( stdin ); // バッファを超えた分は流す
if( buf[0] == '\0' ){ // 入力が空だったら終了
break;
}
printf( "入力行は「 %s 」です。\n", buf );
}printf( "1.これでおしまいっ!\n" );
printf( "2.いっけ〜〜〜〜〜っ\n" );
printf( "3.ズギャーン!!\n" );return EXIT_SUCCESS ;
}
C言語のテストプログラムは、単独で実行すると、こんな動きをします。
% ./a.out ←テストプログラム実行.
hoge ←画面上から入力.
入力行は「 hoge 」です。 ←結果を画面上に出力.
moge ←画面上から入力.
入力行は「 moge 」です。 ←結果を画面上に出力.
だいあきゅーと ←画面上から入力.
入力行は「 だいあきゅーと 」です。 ←結果を画面上に出力.
←空行を入力すると、処理を終える.
1.これでおしまいっ! ←最後に3行のメッセージを出力する.
2.いっけ〜〜〜〜〜っ
3.ズギャーン!!
このテストプログラムを、PHPから呼び出してみます。
% php proc_open.php
入力行は「 いっくよー 」です。 ←C言語からの結果出力.
入力行は「 ファイヤー! 」です。 ←C言語からの結果出力.
入力行は「 ばよえ〜ん!! 」です。 ←C言語からの結果出力.
1.これでおしまいっ! ←最後のメッセージを出力.
2.いっけ〜〜〜〜〜っ
3.ズギャーン!!
command returned 0