lispとrubyとpythonと その4 Cライブラリの呼び出し(まとめ)
それぞれの言語でCと連携してみたまとめ、というか感想というか。
lispもRubyもPythonも呼び出し自体はわりと簡単。
ちゃんと動くかどうかは別として・・・。
一番すんなり理解できたのはSBCLだったような気がする。
Rubyの「拡張ライブラリをCで書く」っていうアプローチが僕にとっては新鮮だった。
CでmallocしたメモリをGCがどんな風に扱うかが気になってGCも調べた。・・・けどよくわかんない。
CommonLisp
CommonLispというか、SBCLだけど。
CのコードをLispにマッピングして書くイメージ。
sb-alien:load-shared-object
ライブラリをロード
sb-alien:define-alien-routine
C関数を呼び出すラッパを宣言
sb-alien:define-alien-type
Cの構造体に対応したデータ構造を宣言
sb-alien:with-alien
Cの変数をレキシカル変数として宣言
sb-alien:make-alien
malloc
sb-alien:free-alien
free
http://www.sbcl.org/manual/History-and-Implementation-of-SBCL.html#index-Garbage-Collection_002c-generational-2
ここ読むとSBCLは保守的GCらしい。
ということはrubyと一緒でコンパクションはしてないのかな。
Ruby
SBCLとは違って、RubyのクラスをCで作るイメージ。
C側で作ってしまえばRubyから使う方はrequire xxxとするだけなので簡単。
Cでクラスを作るときは
#include
が必須
rb_define_alloc_func
newのときに呼び出される関数を登録
rb_define_private_method
rb_define_method
メソッドにあたる関数を登録
RubyのGCはmark and sweepで保守的GC。
1.9でもコンパクションはしないみたい。
Python
ctypesだとloadは
ctypes.CDLL("xxx")
でOKだし、呼び出しもなんとなく通るので楽。
argtype
引数のタイプを指定
restype
戻り値のタイプを指定
メモリのアロケートの仕方はなんだかよくわからない。
PythonのGCは基本が参照カウンタで、循環参照の解決にmark and sweepっぽい仕組みを使ってる。(らしい)
メモリのコンパクションをしてるのかは不明。
参考
GCについて色々見てて見つけたサイト。
保守的GCで豪快にメモリリークするケースの話。
なるほど。。。
http://practical-scheme.net/wiliki/wiliki.cgi?Gauche%3A%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%AF
GCの話が色々
http://tiki.is.os-omicron.org/tiki.cgi?c=v&p=GC
http://tiki.is.os-omicron.org/tiki.cgi?c=v&p=%A5%D7%A5%ED%A5%B0%A5%E9%A5%DF%A5%F3%A5%B0%B8%C0%B8%EC%A4%C8GC
perlは(5.0?)
参照カウント + (スレッド終了時に)マーク・スイープなんだってさ。