mrb_proc_new_cfunc_with_env
mrb_cfunc_env_get
Add API to define cfunc Proc with userdata. · bf6b1df · mruby/mruby
mrubybindではC++のテンプレートを使って、Cの関数を呼び出すためのバインダ関数を自動的に生成することで、mrubyからCの関数を呼び出せるようにしている。バインダ関数は、mrubyから呼び出された引数をC言語の値に変換して、元のCの関数を呼び出し、結果をmrubyの値に変換する。で、このバインダ関数は元のCの関数を知っている必要があるんだけど、上のAPIが追加されるまではmrubyでCの関数が環境を持つことができなかったので、直接は実現できなかった。
そこで以前は、自動的に生成されるバインダの関数の他に、mrubyのdefine_methodでmrubyの関数も生成して、そいつが元のCの関数を保持しておき、バインダ関数に渡すことで実現していた。こうすると実行時にmruby側からCの関数を呼びだそうとした場合には、
そこで以前は、自動的に生成されるバインダの関数の他に、mrubyのdefine_methodでmrubyの関数も生成して、そいつが元のCの関数を保持しておき、バインダ関数に渡すことで実現していた。こうすると実行時にmruby側からCの関数を呼びだそうとした場合には、
- define_methodで生成されたmrubyの関数
- テンプレートで生成されたバインダ関数
- 元のCの関数
と、3段階の関数呼び出しが必要になってしまっていた。
上のAPIを使ってバインダ関数に環境を保持するようにして、
上のAPIを使ってバインダ関数に環境を保持するようにして、
- テンプレートで生成されたバインダ関数
- 元のCの関数
と、2段階の関数呼び出しに減らすことができた。
またそれにより、mrubybindがバインド時に必要だったmrubyで実装していた補助モジュールが一切必要なくなり、Cから呼び出せるAPIだけで実現できるようになった。
Enjoy!