perl から任意の C ライブラリを呼び出す方法
syscall って組込関数でシステムコールはできますけど、libc やその他ライブラリの関数を呼びたい、ってこともありますよね。i386 かつ dlopen な環境なら、こんな風に書けます。
use DynaLoader; use ops; sub ccall { my $r = '1111'; my $s = "\x68" . pack("L", $_[5]) . "\x68" . pack("L", $_[4]) . "\x68" . pack("L", $_[3]) . "\x68" . pack("L", $_[2]) . "\x68" . pack("L", $_[1]) . "\xb8" . pack("L", ("Dyna"."Loader")->can("dl_find_symbol")->(("Dyna"."Loader")->can("dl_load_file")->("libc.so"), $_[0])) . "\xff\xd0" . "\x83\xc4\x14" . "\xa3" . pack("p", $r) . "\xc3"; my $p = pack("P" . length($s), $s); my $f = "my$_[0]"; ("Dyna"."Loader")->can("dl_install_xsub")->($f, unpack("L", $p)); &$f(); unpack("L", $r); } # 実際の呼び出し print ccall("stat", unpack("L", pack("p", "/")));
引数と返り値は syscall のそれと同等。システムコールも libc 経由で実行可能です。これは便利?