2009-01-14
XS入門その5 XSでハッシュリファレンスを扱う
前回のエントリ
XS入門その4 typemap - CとPerlの型変換
から間が開きましたが、前回予告したとおりPerl側からハッシュリファレンスを渡してXS側で処理をするというコードを書きます。
今回まずはコードから先に書きます。最初はハッシュリファレンスを受け取ってハッシュの中身を表示する関数を作成します。
まずはXSモジュール毎回の作業ですがh2xsを実行します
$ h2xs -A -n HashRefXS
として./HashRefXS/HashRefXS.xsを下記のように編集します。
#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" MODULE = HashRefXS PACKAGE = HashRefXS void printHashRef(SV * hash_ref) CODE: HV *hv; // ハッシュ char *hkey; // ハッシュのキー I32 hkeylen; // ハッシュのキーの長さ SV *value; // ハッシュの値 // 引数がリファレンスかどうかチェック if (!SvROK(hash_ref)) { croak("ref(hash) expected"); } // デリファレンスしてハッシュに格納 hv = (HV *) SvRV(hash_ref); // ハッシュの型チェック if (SvTYPE(hv) != SVt_PVHV) { croak("hash expeted"); } // ハッシュのイテレーターの初期化 hv_iterinit(hv); // ハッシュのキーと値を出力する while ((value = hv_iternextsv(hv, &hkey, &hkeylen)) != NULL) { printf("%s : %s\n", hkey, SvPV_nolen(value)); }
作成後に
$ perl MakeFile.PL $ make
します。
前回
Test::Moreを使ってみた
に書いたように./HashRefXS/t/HashRefXS.tにテストを書きます。今回Perlで与えたハッシュのリファレンスの中身をXS側で標準出力に出力しています。そのため、Test::Moreでのテスト(値の比較など)は難しいので、実行の検証コードはHashRefXS.tではなく、./HashRefXS/test.plに実行内容を書きます(方法としていいのか悪いのか分かってませんが)。
test.plは例えば以下のようになります。
#!/usr/bin/perl use strict; use warnings; use HashRefXS; &HashRefXS::printHashRef({a => 1, b =>2, c => 3});
これでmake testします
$ make test # ./HashRefXS/t/HashRefXS.tの実行 # 今回はuse_okのみのテスト PERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/HashRefXS....ok All tests successful. Files=1, Tests=1, 0 wallclock secs ( 0.00 usr 0.01 sys + 0.02 cusr 0.01 csys = 0.04 CPU) Result: PASS # ./HashRefXS/test.plの実行 PERL_DL_NONLAZY=1 /usr/bin/perl "-Iblib/lib" "-Iblib/arch" test.pl c : 3 a : 1 b : 2
内容を習得し、問題なく出力が行えていることが確認できました。
時間が無かったのでXSのソースの部分を詳しく書いていないので暇を見て追記したいと思います。
トラックバック - http://d.hatena.ne.jp/ksmemo/20090114/p1