XSをモジュールなしでロードするには?

よくわかってないんだけど、とりあえず動いたので忘れないようにメモ。
(ただしこれはOSX上でのことなので他のOSだとところどこパスなどで違う部分があると思う)

1. hoge.xsを作る

今回は単純にパッケージ名をPACKAGENAMEで、メソッド名methodnameというのが1つあるだけのhoge.xsだとする。

2. xsubppというコマンドでhoge.xsをhoge.cに変換する

typemapが必要なのでExtUtilsのパッケージの中のを使う。

% xsubpp -typemap /System/Library/Perl/5.8.8/ExtUtils/typemap hoge.xs > hoge.c

3. hoge.cをコンパイルする前にppport.hというのを生成しておく

% perl -MDevel::PPPort -e 'Devel::PPPort::WriteFile()'

4. hoge.cをコンパイルする

コンパイルにはEXTERN.hとかが必要なので、下記のような適当な場所をコンパイルオプションに追加する。これでhoge.oができる。

% gcc -I/System/Library/Perl/5.8.8/darwin-thread-multi-2level/CORE -c hoge.c

5. hoge.oをhoge.bundleにする

gcc -bundle -undefined dynamic_lookup -L/usr/local/lib -bundle hoge.o -o hoge.bundle

6. Perlからhoge.bundleをロードする

以下のようにDynaLoaderの関数を使ってxsで書いたパッケージのメソッドを呼び出すことができる。

#!/usr/local/bin/perl

use strict;
use warnings;
use DynaLoader;

my $libref = DynaLoader::dl_load_file( '/path/to/hoge.bundle' );
my $symref = DynaLoader::dl_find_symbol($libref, 'XS_PACKAGENAME_methodname');
DynaLoader::dl_install_xsub('methodname', $symref);
methodname();

まぁ、こんな感じで動くのは確認したんだけど、そもそものxsubppでなにやってるのかとかDynaLoaderでこうやるとメソッドが呼べるとかの原理は詳しく調べてないので、その辺はあとで調べる。

とりあえず今日はここまで。