ケーズメモ このページをアンテナに追加 RSSフィード

2009-01-14

XS入門その5 XSでハッシュリファレンスを扱う

前回のエントリ

XS入門その4 typemap - CとPerlの型変換

http://d.hatena.ne.jp/ksmemo/20081221/p2

から間が開きましたが、前回予告したとおり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を使ってみた

http://d.hatena.ne.jp/ksmemo/20090111

に書いたように./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のソースの部分を詳しく書いていないので暇を見て追記したいと思います。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証