perlxstut を読んでみたのはいいんだけど,まだ何かできる気がしない.
結果として perlxs を読んだ方が良い気がしてきたので,読みはじめたところ.
で,何か作ってみるかということで,perlxs を読み進めつつ,C の str 系関数を呼び出せるようにする.実用上,何の意味もないけど!!
作ってみるどー!
h2xs -A -n String
を実行すると,関連ファイルと一緒に以下のような String.xs が生成される.
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = String PACKAGE = String
ではでは,XSUB を書いてみませう.
一番シンプルな XSUB は以下の 3 つで構成されます.
- 返り値についての記述
- XSUB の名前
- 引数に関する記述
それに,C の strlen 呼び出しを含めて,strlen はこんな感じに記述できそうです.んじゃ,これを String.xs に追記してみよう.引数の型が括弧内にないのは,昔の C 言語っぽいですね.
size_t strlen(s) const char* s CODE: RETVAL = strlen(s); OUTPUT: RETVAL
関数名と返り値は,異なる行かつ左寄せで記述しないといけないようです.だからこんなのはダメ.だって同じ行にあるもんね.
size_t strlen(s) (略)
というわけで,XSUB では,最初の 2 行で必ず
- XSUB の返り値
- XSUB の名前とその引数
を記述する形になります.
でも実は,同じ行にあっても動いちゃうんだ…!!よくわからないけど!!とりあえず非推奨ってことでいいのかな.
ちなみに,書き方を変えて,こういう風にしても動きます.引数の型情報を,現代の C っぽく括弧内に含める形.
size_t strlen( const char * s ) CODE: RETVAL = strlen(s); OUTPUT: RETVAL
それ以後の行はどうなるかというと,XXX: というようなラベル的なものがない場合は,全部 INPUT: のセクションとして扱われ,INPUT: セクションは次に XXX: の形のものが来るまでの範囲となります.
とりあえず使ってみましょうか!
t/String.t にこんなの書く.
use Test::More tests => 3; BEGIN { use_ok('String') }; is( String::strlen( "aaaaa" ), 5, "length of aaaaa"); is( String::strlen( "kiririmode" ), 10, "length of kiririmode");
んじゃ,テストしよう.
[y-kiri String 05:44:45 ] make test PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/String......ok All tests successful. Files=1, Tests=3, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.02 cusr 0.01 csys = 0.04 CPU) Result: PASS
ってことで,strlen はうまく呼び出せたみたいです!