XSをモジュールなしでロードするには?
よくわかってないんだけど、とりあえず動いたので忘れないようにメモ。
(ただしこれはOSX上でのことなので他のOSだとところどこパスなどで違う部分があると思う)
2. xsubppというコマンドでhoge.xsをhoge.cに変換する
typemapが必要なのでExtUtilsのパッケージの中のを使う。
% xsubpp -typemap /System/Library/Perl/5.8.8/ExtUtils/typemap hoge.xs > hoge.c
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でこうやるとメソッドが呼べるとかの原理は詳しく調べてないので、その辺はあとで調べる。
とりあえず今日はここまで。
XSむずい
id:zigorouさんの記事を見ながらXSを書いてる。
モジュールにしないでXSを使うことって出来るのかなあ。
ソフトウェアのライセンスは難しくてわからないなー
LGPLライセンスのCのライブラリ(libなんちゃら)を自分のCPANモジュール(Perl and GPLライセンス)に同梱したいんだけど問題があるのかないのかわからん。
Cのライブラリの作者にメールとかするのはいいとして、ライセンス的に問題ないかがよくわかりません。
今のところ大きく分けて2つ疑問があります。
1つは
http://ja.wikipedia.org/wiki/GNU_Lesser_General_Public_License
↑この辺を見る限り、CPANモジュールならソースはすべて公開になっているわけだから、LGPLを同梱するのは問題なさそうな気もするけどどうなのか?
もう1つは、LGPLだとそのライブラリを使用するソフトウェアをGPLに準拠させなきゃいけないんだけど、今回のケースの場合、そのライブラリを使用するCPANモジュールがPerl and GPLっていうライセンスになっててこれでGPLに準拠していると言えるのか?(Perlライセンスにもなってるのが気になる)
この辺詳しい人いませんか!
スレーブのレプリケーションが遅れてたら
DBがマスタ-スレーブ構成になってる場合で、定期的(例えば1日1回とか)にテーブルを作成するようなアプリがあったとします。
それで、普通にWRITEはマスタでREADはスレーブとかやってると、スレーブへのレプリケーションが遅れたりしてスレーブがSELECTしたときにスレーブにテーブルがないという可能性が0ではないと思うのですが、SELECTするプログラム部分をevalしてテーブルがないとエラったらマスタにつなぐのが普通かなぁと思うんだけど、他にいい方法があるんでしょうかねぇ。
ちなみに言語はPerlです。
↓こんな感じにする以外でいい方法あるのかな
my $dbh = DBI->connect( @slave_datasource ); my $sth = $dbh->prepare("SELECT * FROM foo"); eval { $sth->execute() }; if ( $@ ) { my $dbh = DBI->connect( @master_datasource ); my $sth = $dbh->prepare("SELECT * FROM foo"); $sth->execute(); } # do something...
r->headers_inなどのapr_table_tのデータの扱い方
r->headers_in は apr_table_t 型で、apr_table_elts() という関数を使うと apr_array_header_t 型の値が取得できる。
これが先頭のデータになる。
const apr_array_header_t *arr = apr_table_elts(r->headers_in);
で、apr_array_header_t は下記のような構造体になってる。
struct apr_array_header_t { apr_pool_t *pool; int elt_size; int nelts; int nalloc; char *elts; };
この elts は char * なんだけど、apr_table_entry_t になっているっぽい。
なので、
apr_table_entry_t *elts = (apr_table_entry_t *)arr->elts;
こうやって apr_table_entry_t * として受けとると最終的には、
for (i = 0; i < arr->nelts; i++) { printf("%s: %s", elts[i].key, elts[i].val); }
とやるとkeyとvalが出力できる。
ちなみに、arr->elts はもともと char * なので (apr_table_entry_t *) でキャストしてやらないとwarningが出ます。