lispとrubyとpythonと その4 Cライブラリの呼び出し(まとめ)

それぞれの言語でCと連携してみたまとめ、というか感想というか。
lispRubyPythonも呼び出し自体はわりと簡単。
ちゃんと動くかどうかは別として・・・。
一番すんなり理解できたのは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?)
参照カウント + (スレッド終了時に)マーク・スイープなんだってさ。