この記事は情報が古いです。
現在ではRuby-FFIもクラスインスタンス変数 @ffi_functions
に関数は登録されています
モチベーション
コールバックとして、attach_function した関数を利用したい
はじめに
Ruby-FFI と Fiddle はRubyからC言語の関数を呼び出せる便利なライブラリです。
- Ruby-FFIでは、
attach_function
メソッドを利用して、関数を登録します。 - Fiddleでは、
extern
メソッドを利用して、関数を登録します。
それぞれ Function
クラスが存在します。しかし何もしなければRubyではガベージコレクションが働いて関数を表現しているオブジェクトを開放してしまいます。開放された関数オブジェクトを呼び出そうとするとセグフォが発生してしまうはずです。ですから関数オブジェクトは、どこかのオブジェクトから参照されてGCから保護されているはずです。では attach_function
や extern
で作成した関数オブジェクトはどこに登録されているのでしょうか?
Ruby-FFIではクラス変数
Ruby-FFIでは、関数はクラス変数に退避されています。クラス変数の一覧は、class_variable
メソッドで閲覧できます。
HogeLib::FFI.class_variables
たとえば、こんな感じで、一つの関数が、同名の一つのクラス変数に保存されています。
(略)
:@@sam_hdr_init,
:@@bam_hdr_read,
:@@bam_hdr_write,
:@@sam_hdr_destroy,
:@@sam_hdr_dup,
:@@sam_hdr_parse,
:@@sam_hdr_read,
(略)
Fiddleでは、クラスインスタンス変数
Fiddleでは、関数は、@func_map
というクラスインスタンス変数に登録されています。
HogeLib::FFI.instance_variable_get(:@func_map)
とすれば見ることができます。ただし、@func_map
は内部のAPIだと思います。この先とくに予告なく変更される可能性があります。そのため特に必要なとき以外は、安易にアクセスしない方が良いとは思いますが、とにかく現状ではこのような実装になっています。
この記事は以上です。