ラベル XS の投稿を表示しています。 すべての投稿を表示
ラベル XS の投稿を表示しています。 すべての投稿を表示

2009/04/13

XSからlibcのputs関数を呼び出す

前回はCのコードをxsコードに書いて、それを実行するということをやりました。
今回は外部のCライブラリを呼び出してみたいと思います。
一番簡単そうな例として、libcのputs関数を呼び出してみます。

まずはXSライブラリのひな形を作成します。
$ h2xs -A -n libcXS
perl Makefile.PL


次にXSソース(libcXS.xs)を編集します。
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include "stdlib.h"

MODULE = libcXS PACKAGE = libcXS

void
puts(value)
char * value

追記したのは、include部にstdlib.hを追加したのと前回も追加した関数の戻り値などの定義部分です。
前回のようCODEセクションを定義してコードを書かなくても、既存のライブラリ呼び出しの場合は定義だけでOKです。

最後にmakeして完了です。

実際にこのモジュールを使ったPerlコードを使った例が次のものです。
標準出力にhogehogeと表示されるはずです。
#!/usr/bin/perl

use strict;
use ExtUtils::testlib;
use libcXS;

libcXS::puts("hogehoge");


だんだんわかってきたような気がしてきていますが、きちんと理解するためにはもう少し時間がかかりそうです。
ひとまず、perldoc perlxsとモダンPerl入門を改めて読んでみます。

----
追記:
なぜか、#include "stdlib.h"を消しても動きます…
前段階でincludeされてるのかなぁ、それとも別の原因…?
今度は違うライブラリでやってみたいと思います。

2009/04/07

XSを使ってみる

PerlからC APIを呼ぶ仕組みでXSというものがあります。
これにより、Cで書いた部分の処理に関しては高速になったり、既存のCで書かれたライブラリが使用できるようになるらしいです。
ちょっとおもしろそうなので、練習に動かしてみました。

モダンPerl入門に詳しく書いてあったのですが、ちょっとやることが多すぎたので下記のサイトの例をやってみました。
http://d.hatena.ne.jp/higepon/20050615/1118829090

手順は上記のサイトに書いてある通りに行いました。
$ h2xs -A -n MyTestXS ←XSのひな形を作成
$ cd MyTestXS/
$ perl Makefile.PL ← Makefileを作成
[MyTestXS.xsを編集]
$ make


MyTestXS.xsは次のように編集しました。
ちなみにMODULE = MyTestXSまでは自動的に作成されてました。
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"


MODULE = MyTestXS PACKAGE = MyTestXS

int
increment2(value)
int value
CODE:
RETVAL = value + 2;
OUTPUT:
RETVAL

追記した部分は、まず戻り値の型、関数名、引数名と型を指定します。
CODEより後ろには実際のCのコードを記述します。
OUTPUTに戻り値を指定します。

makeして失敗がなければ、XSモジュール作成完了です。
では、実際に使ってみつつ、ベンチマークもやってみました。
下記のようなコードを書きました。これも参考サイトと同じです。
#!/usr/bin/perl
use strict;

use ExtUtils::testlib;
use MyTestXS;

use Benchmark;

my $count = 5000000;
timethese($count,
{
'XS' => 'xs_test();',
'Perl' => 'perl_test();',
});

sub xs_test {
MyTestXS::increment2(100);
}

sub perl_test {
increment2(100);
}

sub increment2 {
$_[0] + 2;
}

これを実際に私のMacBookで実行してみると下記のような結果になりました。
macbook:MyTestXS hiroki$ perl ./test.pl 
Benchmark: timing 5000000 iterations of Perl, XS...
Perl: 5 wallclock secs ( 5.95 usr + 0.08 sys = 6.03 CPU) @ 829187.40/s (n=5000000)
XS: 3 wallclock secs ( 3.46 usr + 0.04 sys = 3.50 CPU) @ 1428571.43/s (n=5000000)

XSで書いた方が2倍近くパフォーマンスが良いです。

私としては、はやく動かすというよりも既存のCライブラリをPerlから使いたいと思ってるので、引き続き調べます。
モダンPerl入門を見ると詳細に書いてあるようで。