Skip to content

Pitfalls

tsahara-iij edited this page Oct 31, 2012 · 4 revisions

C で拡張を実装する際の注意事項

"arena overflow error"

C関数から多数の mruby オブジェクトを生成した場合にこのエラーが発生することがある。 対処としては、オブジェクトをたくさん生成する前後を mrb_gc_arena_save() と mrb_gc_arena_restore() でくくれば良い。

int ai = mrb_gc_arena_save(mrb);
...たくさんのオブジェクトを生成するコード...
mrb_gc_arena_restore(mrb, ai);

mrb_yield を使う時の注意点

C関数の中から mrb_yield を呼び、その中でオブジェクトが生成される場合も "arena overflow error" と同様の対処が必要となるようだ。こちらは "arena overflow error" よりわかりにくいため注意すること。

RSTRING_PTR(str) を使う前に三回考えること

mruby の String は、内部表現としては char * のバイト列で保持されている。 しかし、これらは 必ずしも一対一には対応しない。 NUL 文字が含まれていればもちろん、そうでなくとも RSTRING_LEN(str) が strlen(str) と異なるケースがままある。 したがって、mrb_str_new2() 等で文字列を生成した直後など RSTRING_PTR(str) の内部表現が確信できる場合以外には RSTRING_PTR(str) は使ってはならない。 あまり考えずに Ruby 文字列から C 文字列がほしい場合は mrb_str_to_cstr(mrb, str) を使うこと。 この関数が返してきた C 文字列は strlen(s) == RSTRING_LEN(str) が保証される。 なお NUL 文字を含む場合は mrb_raise() により例外が上がる。

参考: Tips

Clone this wiki locally