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

454
-1

Published on

Go Conference 2015 Winter 発表資料

Published in: Software
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
454
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

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. ご静聴 ありがとう ございました
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×