Hatena::Groupdann

優しいXS入門

優しいXS入門

XS学び方入門

http://d.hatena.ne.jp/tokuhirom/20090624/1245812352

開発のステップ

Cのライブラリをラップするステップ

テンプレートから生成

  • h2xsで?
  • Module::Install::XSUtilを使ったものにしたほうがいいかも(後で)
    • src, includeの設定
  • xssetupというものを作ってみた。これを改善していく。

typemap作成

INPUT, OUTPUT
INPUT

引数に該当の方が指定された場合に挿入されるコードを記述

  • $varがXS関数内で使用する変数
  • $argが引数
  • $typeがC型名
OUTPUT
  • $argは戻り値として使われるSV
  • $varは戻り値に代入したい変数

Cでのライブラリのラップ

src/*.cに、Cのライブラリをラップするコードを実装して配備。

(全部.xsにかくのも、小さめなのだったらそれでもいいのかも)

ヘッダ配置

includeに.hを置く

XS開発

make

perl Makefile.PL; make

テスト

prove -b t/*.t

use blib したスクリプトで実際に使ってみるとか

イディオム

定数定義

Text::Migemoから。

#define NEED_newCONSTSUB

static void
init_constants()
{
    HV *stash;
    stash = gv_stashpv("Text::Migemo", 1);
    newCONSTSUB(stash, "MIGEMO_DICTID_MIGEMO",      newSViv(MIGEMO_DICTID_MIGEMO));
    newCONSTSUB(stash, "MIGEMO_DICTID_ROMA2HIRA",   newSViv(MIGEMO_DICTID_ROMA2HIRA));
    newCONSTSUB(stash, "MIGEMO_DICTID_HIRA2KATA",   newSViv(MIGEMO_DICTID_HIRA2KATA));
    newCONSTSUB(stash, "MIGEMO_DICTID_HAN2ZEN",     newSViv(MIGEMO_DICTID_HAN2ZEN));
    newCONSTSUB(stash, "MIGEMO_DICTID_INVALID",     newSViv(MIGEMO_DICTID_INVALID));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_OR",         newSViv(MIGEMO_OPINDEX_OR));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_NEST_IN",    newSViv(MIGEMO_OPINDEX_NEST_IN));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_NEST_OUT",   newSViv(MIGEMO_OPINDEX_NEST_OUT));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_SELECT_IN",  newSViv(MIGEMO_OPINDEX_SELECT_IN));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_SELECT_OUT", newSViv(MIGEMO_OPINDEX_SELECT_OUT));
    newCONSTSUB(stash, "MIGEMO_OPINDEX_NEWLINE",    newSViv(MIGEMO_OPINDEX_NEWLINE));
}

XS学習項目

ppport.h

typemap


  • OUTPUTセクションは、コンパイラーに対してどのようにしてC の型をPerlが認識できる値に変換するのかを指示します。

TYPEMAPセクションは、コンパイラーに対して指示されたCの型をPerlの値にマッピングするのに使うべきINPUTセク-ションもしくはOUTPUTセクションにあるコード片を指示します。


メモリー管理

Debugging

printデバッグ

PerlIO_printf(PerlIO_stderr(), "debugdebug")

xsubppで生成されたcコードを見てみる

メモリーリーク

メモリリークのチェック

http://d.hatena.ne.jp/tokuhirom/20090702/1246523440

prove --exec 'perl -Iblib/lib -Iblib/arch -MTest::Valgrind' t/*.t
レファレンスカウントの確認

Devel::Peekでレファレンスカウント見る

use Devel::Peek "Dump";
print Dump(MyXS::hoge()) . "\n";
gdb
ExtUtils::testlib

Profiling

valgrind

valgrind --tool=callgrind --dump-instr=yes --trace-jump=yes PROG
  1. kcachegrind