PHP Extensionの作り方 その2 引数・返り値編
引数と返り値がなければ、やりたいことできなくね?
前回(その1基本編)で作った関数に引数を追加してみる。
スカラ型は楽に扱えるけど、配列・リソースは少しコードが長くなるので省略。
php-src/ext/delaemon/delaemon.c
引数の定義
/* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_delaemon, 0) ZEND_ARG_INFO(0, arg_int) ZEND_ARG_INFO(0, arg_str) ZEND_END_ARG_INFO() /* }}} */
関数と引数の紐付け
const zend_function_entry delaemon_functions[] = { PHP_FE(confirm_delaemon_compiled,>NULL) /* For testing, remove later. */ PHP_FE(delaemon, arginfo_delaemon) /* ←ここ */ PHP_FE_END>-/* Must be the last line in delaemon_functions[] */ };
関数の実装
PHP_FUNCTION(delaemon) { long arg_int, arg_str_len; char *arg_str; char res[100]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &arg_int, &arg_str, &arg_str_len) == FAILURE) { return; } /*ここで呼び出しもとで渡した引数を受け取ってる*/ sprintf(res, "arg1 = %ld, arg2 = %s", arg_int, arg_str); RETURN_STRING(res, 1); /*返り値用マクロ、他の型のも定義されてる*/ }
zend_parse_parametersでstrを受け取るときはバイト数も返されるので入れ物が必要。
何気にハマった。
テスト用のPHPファイル
cat test_call.php <?php dl('delaemon.so'); $res = delaemon(5, 'Rock'); var_dump($res); ?>
実行する
$ php test_call.php string(21) "arg1 = 5, arg2 = Rock"
以上。
実装したい内容がわかっていれば、それと類似している
ことをやっていそうな組み込み関数の実装を調べると
マクロやzend_xxx系メソッドの使い方など色々と参考になると思います。