Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PHPの拡張モジュールをGoで作る

9,394 views

Published on

Go Conference 2015 Winter 発表資料

Published in: Software
  • Be the first to comment

PHPの拡張モジュールをGoで作る

  1. 1. Writing PHP extension in Go PHPの拡張モジュールを
 Goで作る Go Conference 2015 Winter (2015/12/5) 発表資料
  2. 2. 自己紹介 ❖ @hnw ❖ KLab株式会社所属 ❖ PHPの方から来ました
  3. 3. 基本的にcgoの話です ご安心ください
  4. 4. cgoとは ❖ Goのコメント部でCプログラミングする仕組み ❖ コンパイラオプション ❖ リンカオプション ❖ Cプログラム本体
  5. 5. PHP拡張モジュールとは ❖ PHP起動時にロードすることでPHPに機能追加を行う ❖ 通常はC言語で記述する ❖ PHPのクラスや関数を実装できる ❖ 実体は共有ライブラリ
  6. 6. PHP拡張モジュールとは ❖ PHP起動時にロードすることでPHPに機能追加を行う ❖ 通常はC言語で記述する ❖ PHPのクラスや関数を実装できる ❖ 実体は共有ライブラリ ❖ Go 1.5から共有ライブラリが出力できる ❖ PHPからGo資産を使う未来…?
  7. 7. 大方針:GoとCを併用 ❖ 現時点ではGoだけで全部書くのは難しい ❖ Goで共用体をうまく扱えない点が一番ネック ❖ 将来的にはGoだけで書いた方が楽になりそう
  8. 8. 具体的な手順(1) ❖ PHPで普段通りに拡張モジュールを作る ❖ PHPのext_skelでひな形を作る ❖ 関数をCで実装する ❖ 関数内でGoで作った関数を呼び出す ❖ 拡張モジュールを静的ライブラリとしてビルドする ❖ cgoでgoコードとリンクして共有ライブラリにする
  9. 9. 具体的な手順(2) $ phpize! $ perl -i.bak -pe 's/^enable_static=no/ enable_static=yes/;' ./configure! $ ./configure! $ make! $ mv modules/phpimpl.a modules/libphpimpl.a! $ go build -buildmode=c-shared -ogoext.so goext.go! $ install goext.so $(php-config --extension-dir) ❖ 結構つらかった…
  10. 10. ❖ 静的ライブラリを-lでリンクする ❖ リンク時に解決できないシンボルがあっても無視 cgoの環境変数の指定 /*! #cgo LDFLAGS: -L${SRCDIR}/modules -lphpimpl ! -undefined dynamic_lookup! */
  11. 11. PHP関数からGo関数を呼びだす PHP_FUNCTION(fib)! {! ! int n;! ! if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &n) == FAILURE) {! ! ! return;! ! }! ! RETURN_LONG(fib(n));! }
  12. 12. ❖ exportを指定すればC関数から呼び出せる 呼び出される側のGo関数 //export fib! func fib(n int) int {! ! if n < 2 {! ! ! return n! ! }! ! return fib(n-2) + fib(n-1)! }
  13. 13. ❖ PHP関数 phpversion() を呼び出す例 ❖ マクロが使えないけど、そこそこ戦える! GoからPHP関数を呼びだす var retval C.zval! C.zend_call_method(nil, nil, nil,
 C.CString("phpversion"),! C.size_t(len("phpversion")),! &retval, 0, nil, nil)
  14. 14. ノウハウ ❖ 現在のcgoの制限 ❖ Cマクロが使えない ❖ 共用体がうまく扱えない ❖ 型の変換などはPHP側(C実装側)でやるべき ❖ PHPはマクロも共用体も多用しているため ❖ 必要ならマクロ関数のラッパー実装を作る
  15. 15. ❖ Go側のmain関数は呼ばれないけど必須 ❖ main関数内でPHP側のC関数を呼び出しておく ❖ Go側で使っていないとリンクしてくれない ビルド時の苦労(1) func main() {! /* PHP extensionの*.oをリンクするためのトリック */! C.get_module()! }
  16. 16. ビルド時の苦労(2) ❖ GoもPHPも他の言語との連携を考慮していない印象 ❖ 現時点ではmake一発みたいな状態ではない ❖ Autoconfに寄せたいけど面倒そう…
  17. 17. まとめ ❖ PHPの拡張モジュールをGoで記述できた ❖ cgoで*.soをビルド ❖ PHPとGoとで双方向に呼び出せた ❖ Go→PHPは気軽とは言えない ❖ 詳細はブログ記事に書きます
  18. 18. ご静聴 ありがとう ございました

×