読者です 読者をやめる 読者になる 読者になる

Hokkaido.pm#8に来ています

Perl

ゲストとしてtypesterさんが来てくれているので、XSの話をリクエストしたところ実際にライブコーディングまで見せていただけたので非常に興奮しております。

## XSにまつわる話

- 2010年から書き始めた
- XS食わず嫌い期
    - 2004-2010年くらいまで
    - 手を出すまでは意味わからない
- iOSアプリ
    - AMF/RTMP
    - Data::AMF::XSを書いた
        - .xsではなくてもXSは書ける
    - Data::AMFをもともと作っていた
- XSとは
    - Perlと外の世界をつなぐもの
    - ライブラリのバインディングを作るための仕組み
    - 高速というのは異端
        - 本来の目的ではない
        - うまくXSを使っているのがgfx
    - 基本的には早くならない
    - ライブラリを普通に書いて、XSでバインディングを書く
    - 計算部分だけXSとかはいいけど
- 必要なもの
    - ライブラリの使い方
    - XSのマクロの使い方
    - Perl <-> Cのデータ変換
- ターゲットライブラリ
    - Cocoa APIは慣れているし、libmsgpack, libev, libuvも
    - iPhone向けにビルドしておいて、置いている
- XSマクロ
    - perldoc perlxstut, perlxs
        - 参考書
- オブジェクトの変換
    - SVからCの変数に
    - perlguts
        - SV, AV, HV
            - それぞれキャストして使える
        - オブジェクトの変換についてはperlgutsを見る
- XSモジュールの作り方
    - Module::Install::XSUtil
        - XS神(== gfx)製
        - 2009年のアドベントカレンダー
    - Module::Build::Pluggable::XSUtil とか
- どうやってつくっているのかデモ
    - Discount(Cで書かれたmarkdownのライブラリ)を使ってXSを書く
    - 初期化が2種類ある
        - ファイルからなのか、stringからなのか
        - 構造体のポインタが返ってくる
            - $self的な
    - p5-discountを作ってみる
        - gitのsubmodule使っておくと楽
            - depsに入れておく
        - git co 2.1.5a してaddしてcommitしておくとdeps以下に入るので便利
        - ./configure.sh たたいて make
            - static linkのlibmarkdown.aをXSモジュールに入れておく
            - どこらへんでも入ってるのはリンクするだけでもいい
        - .a をperlから使う
    - Module::Install::XSUtilを使って書く
        - cc_warnings;でコンパイル時に警告
        - use_ppport;はDevel::PPPortのppport.hを生成してくれる
            - Perlのバージョン間のマクロの違いを吸収してくれる
            - 3.20
        - makemaker_args->{MYEXTLIB}
            - .aファイルの場所
            - $(LIB_EXT)がプラットフォームごとを吸収してくれる
        - MY::postambleにMakefileを書くと一緒に実行される
            - depsのなかに入って configure たたく
        - lib/Discount.pm書いてmakeする
            - できた、これだけ
            - 今回はstatic linkで内包している
            - ほかにリンクする場合は
                - OpenSSLだったら
                - cc_libs -lssl;すると勝手にリンクしてくれる
        - コンパイルしたけど通った
            - .xsとか.cとかない
        - Discount.xsを書く
            - 最初は定型でC
            - MODULE= PACKAGE= からがXS
            - BOOT: {}
                - useしたときに
                - ライブラリが読み込まれたら実行されるブロック
                - 初期化したいときとかに
            - 普通の関数
                - 戻り値を関数名は分ける
                - CODE: {}
                    - 関数の中身
                - makeするとblib/に入る
                    - use blib '.'; しておくとパスを通すことができる
                    - perl -Mblibするけど、use blibしておかないとflymake通んないし。。
                - BOOTが呼ばれた
            - char*で引数を渡す
                - Perlから文字列渡してるのにchar*になってる
                    - XSの型変換の仕組み
                        - 自動的に変換して渡してくれる
                    - 返り値も自動で変換してくれる
                    - 使いまくってXSを書くとコード量が減る
                    - xsubppでCに変換されている
                        - それをビルドしているだけ
                        - Discount.cが生成されている
                            - .xsのMODULE= PACKAGE= までは変換されない
            - OUTPUT: {}
                - RETVAL
                    - 返り値
            - 完成品どうぞ
            - cc_src_paths 'src';でXSのコードに移しておける
            - ライブラリのコードを書くだけでバインディングができる
            - MODULE= PACKAGE= PREFIX=を書いておけば
            - ライブラリの構造体は自動変換されない
                - typemapに書いておけば自動変換される
    - XSでObjective-C
        - xsubppで生成されたcを自分で書けばいい
            - .mで書く
        - .xsでObjective-Cを書く
            - xsubppでは.cに変換されるので.mでリネームする
            - 楽だけど、どこでフックしよう
    - MacRuby的なの?
        - PerlでMacアプリじゃなくて、Macの機能にアクセスしたいだけだし
        - 単体モジュールにしていったほうがみんなが幸せに
        - Objective-Cとかrefcount方式だし,  Mooseっぽいし
        - アプリはobjcで書きましょう
- まとめ
    - 外の世界をつなぐもの
    - Perlと外の両方の知識が必要
    - 「自分でそのライブラリを勉強しつつかく」
    - 牧さんのXSのコードはきれい
        - Text::Mecab, ZMQとかめちゃくちゃ綺麗
    - 一回書いたらコピペでいける