前回は、引数や戻り値について、値渡しをしたのだが、今回はポインタを使ってみる。
ポインタを使用する場合、それを表すクラスを使用するのだが、Ruby か Rust のどちらでメモリ領域を確保したかにより、使用するクラスが異なる。
Ruby 側でアロケートしたメモリについては、FFI::MemoryPointer を使用し、Rust 側でアロケートしたメモリについては、FFI::Pointer を使用する。
FFI::MemoryPointer の場合
確保された領域については、Ruby のGC が自動で解放してくれる。
FFI::Pointer
次に、Rust 側でヒープ領域のメモリを確保し、FFI::Pointer
を使用して、Ruby 側で参照してみる。
先ほどの、FFI::PointerMemory で、確保され場合と異なり、 Rust 側で確保されたメモリ領域は、GC により解放されないので、Rust 側で解放する必要がある。
ポインタを使用すれば、色々と複雑なデータ構造も扱えるようになる。 しかし、Ruby と Rust を連携させるといった場面ではあまり使わない方が良い気がした。
使うと Rust 側のコンパイル時にメモリ管理をチェックするといった機能の旨みを半減させてしまいそうな気がする。(unsafe だらけになってしまいそう。) なので、既存のライブラリを使用するなどのの理由がない限り使用しない方が良さそう。 Ruby と C との連携にはよく使いそうな感じはするのだが。。。
ポインタが必要な場合は、なるべくFFI::MemoryPointer を使用して、メモリ管理は Ruby に任せた方が良いかも。