&reftitle.examples;
FFI の基本的な使い方 FFI API の詳細に深く立ち入る前に、よくあるタスクに対する FFI API の使い方が どれほど簡単かを示す例をいくつか見てみましょう。 これらの例の中には、libc.so.6 を必要とするものがあります。 それらは、このライブラリが利用できないシステムでは動きません。 共有ライブラリの関数を呼ぶ printf("Hello %s!\n", "world"); ?> ]]> &example.outputs; C の関数のうちのいくつかは、特定の呼び出し規約 (例: __fastcall__stdcall,__vectorcall など) を必要とすることに注意してください。 関数を呼び出し、構造体を引数経由で返す new("struct timeval"); $tz = $ffi->new("struct timezone"); // C の gettimeofday() を呼ぶ var_dump($ffi->gettimeofday(FFI::addr($tv), FFI::addr($tz))); // C のデータ構造のフィールドにアクセスする var_dump($tv->tv_sec); // C のデータ構造全体を出力する var_dump($tz); ?> ]]> &example.outputs.similar; int(0) ["tz_dsttime"]=> int(0) } ]]> 既存の C の変数にアクセスする errno); ?> ]]> &example.outputs; C の変数を作成して書き換える cdata); // 単純な代入 $x->cdata = 5; var_dump($x->cdata); // 複合代入 $x->cdata += 2; var_dump($x->cdata); ?> ]]> &example.outputs; C の配列を扱う ]]> &example.outputs; C の enum を扱う ZEND_FFI_SYM_TYPE); var_dump($a->ZEND_FFI_SYM_CONST); var_dump($a->ZEND_FFI_SYM_VAR); ?> ]]> &example.outputs;
PHP のコールバック PHP のクロージャを、関数ポインタ型のネイティブ変数に代入したり、 関数の引数として渡したりできます。 PHP の <classname>Closure</classname> を C の関数ポインタに代入する zend_write; $zend->zend_write = function($str, $len) { global $orig_zend_write; $orig_zend_write("{\n\t", 3); $ret = $orig_zend_write($str, $len); $orig_zend_write("}\n", 2); return $ret; }; echo "Hello World 2!\n"; $zend->zend_write = $orig_zend_write; echo "Hello World 3!\n"; ?> ]]> &example.outputs; これは動作こそしますが、この機能は libffi が動作するすべてのプラットフォームでサポートされているわけではありません。 また、非効率的であり、リクエストの終了時にリソースがリークします。 したがって、PHP のコールバックの使用は最小限にすることを推奨します。
PHP/FFI/事前ロードの完全な例 php.ini preload.php ]]> dummy.h dummy.php printf($format, ...$args); } } ?> ]]> test.php printf("Hello %s!\n", "world"); ?> ]]>