Perlテックブログ

ITエンジニアの成長意欲を刺激する技術考察、モジュール開発の日記。Perlイベントや国内や海外のPerlの記事の紹介。

Perl XSポータビリティノート

Perlは、スクリプト言語なので、それぞれのOSの互換性については、Perlインタプリタが面倒を見てくれる。

でもXSの世界に降りてくると、C言語を書くので、モジュール作者がポータビリティを保証しないといけない。これがXSの辛いところの一つ。

64bitのLinuxで動いても、そうそうそのままには、FreeBSDWindows、32bitのLinuxでは動かないんだなこれが。

だから、気が付いた点はここでノートしておこうと思う。

reallocは危ない

reallocは使わないほうがよい。機能や効率的には、まったく悪くはないんだけれど、reallocの内部実装が各OSによって異なるために、メモリが再利用されたり、再利用されなかったりする。

自分の環境では正しく動いているのに、他の環境ではエラーとなっても、原因をつかみにくい。

だから、mallocとfreeを使って、メモリ確保したほうが、各OS間で、差がでなくってよい。

ファイルを一度に読み込むときはバイナリモードで

ファイルを一度に読み込むときはしっかり、バイナリモードで。

fopen(cur_file, "rb");

Linuxだと"r"でも動くんだけど、Windowsだた"rb"でないと正しく動かない。

Windowsのdllは、関数名を明示的に指定する必要がある

Linuxの場合は、共有ライブラリを作成するときに、関数名をしてしなくっても動くけれど、Windowsのdllだとこれがないと動かない。以下はExtUtils::CBuilderの例だけど、dl_func_listをしっかり忘れずに。

  my $shared_lib_file = $cbuilder->link(
    objects => $object_files,
    module_name => $module_name,
    dl_func_list => $native_func_names,
    extra_linker_flags => $extra_linker_flags
  );

64bit整数を表現する文字列の解析にはstrtoullを

Linuxでは、strtoulで、64bit整数を表現する文字列を正しく解析できるが、Windowsではだめ。64bit整数を表現する文字列の解析にはstrtoullを使いましょう。

              uint64_t unum = (uint64_t)strtoull(num_str, &end, digit);

警告を出すのは開発環境だけ

「-Wall」などで警告を出すのは、自分の開発環境だけにしておく。gccのバージョンが他の環境で、ちょっと異なるだけで、余計な警告がでてしまう。

アラインメントセーフな実装に

データの基本サイズは、int32_tのサイズの倍数で表現するようにして、アラインメント境界をまたいでしまうint64_t型やdouble型データは、memcpyでコピー。

int32_t型は、何かと苦労の少ない型だ。32bitCPUのアドレス型のサイズに収まる。データの基本サイズを32bit整数型にしておいて、詰めて配置して、アラインメント境界をまたぐようなデータは、memcpyでまるっとコピー。これが、楽だ。