[PHP] Embed SAPIでCからPHPを呼び出してみる その2では、zend_eval_stringlを使って、文字列をPHPスクリプトとして解釈、実行してみた。
今度は定義済みのPHP関数をCから呼び出してみよう。
※今回も同様に、Linux上で、PHP 7.1.1を使った例。
call_func.c
ここはほぼ前回と一緒だけど、今回は最終的な値がないので、第3引数にNULLを渡している。
関数名、引数値もすべて、zvalにする必要があるため、ZVAL_STRINGやZVAL_LONGといったマクロを使って、Cの値からPHPの値に変換する。
18行目で、call_user_functionを使って、関数を呼び出す。
この時、関数が登録されているテーブルを渡す必要があるけど、SAPIのグローバルテーブルの場合は"EG(function_table)"を渡せばいい。
19-21行目の戻り値の扱いは前回と同じで、LONG型のzvalから値をCのlongとして取り出している。
今度は定義済みのPHP関数をCから呼び出してみよう。
※今回も同様に、Linux上で、PHP 7.1.1を使った例。
全体
CからPHPの定義済み関数を呼び出すにはcall_user_functionを使う。call_func.c
#include <string.h> #include <sapi/embed/php_embed.h> int main(int argc, char *argv[]) { PHP_EMBED_START_BLOCK(argc, argv) char php_src[] = "function add($x, $y) { return $x + $y; }"; int stat = zend_eval_stringl(php_src, strlen(php_src), NULL, "phpsrc"); printf("%d\n", stat); zval func = {{ 0 }}; ZVAL_STRING(&func, "add"); zval args[2]; ZVAL_LONG(&args[0], 2L); ZVAL_LONG(&args[1], 3L); zval ret = {{ 0 }}; call_user_function(EG(function_table), NULL, &func, &ret, 2, args); printf("%d\n", Z_TYPE(ret)); printf("%d\n", Z_TYPE(ret) == IS_LONG); printf("%ld\n", Z_LVAL(ret)); PHP_EMBED_END_BLOCK() return 0; }
関数定義
7-9行目で、zend_eval_stringlを使って、PHPのユーザ定義関数を定義している。ここはほぼ前回と一緒だけど、今回は最終的な値がないので、第3引数にNULLを渡している。
関数呼び出し
11-16行目で、呼び出す関数の関数名、引数値、戻り値用変数を用意している。関数名、引数値もすべて、zvalにする必要があるため、ZVAL_STRINGやZVAL_LONGといったマクロを使って、Cの値からPHPの値に変換する。
18行目で、call_user_functionを使って、関数を呼び出す。
この時、関数が登録されているテーブルを渡す必要があるけど、SAPIのグローバルテーブルの場合は"EG(function_table)"を渡せばいい。
19-21行目の戻り値の扱いは前回と同じで、LONG型のzvalから値をCのlongとして取り出している。
ビルド & 実行
$ export PHP_INCLUDE=/path/to/include/php $ gcc -Wall -I$PHP_INCLUDE -I$PHP_INCLUDE/main -I$PHP_INCLUDE/Zend -I$PHP_INCLUDE/TSRM -I$PHP_INCLUDE/sapi -L/path/to/lib -lphp7 -o call_func call_func.c $ LD_LIBRARY_PATH=/path/to/lib ./call_func 0 4 1 5
0 件のコメント:
コメントを投稿