# Foreign Function Interface - FFI
## Libraries and C++ Primitives vs. FFI
There are two ways to "drop to C" in Rubinius. Firstly, primitives are special
instructions that are specifically defined in the VM. In general they are
operations that are impossible to do in the Ruby layer such as opening a file.
Primitives should be used to access the functionality of the VM from inside
Ruby.
FFI or Foreign Function Interface, on the other hand, is meant as a
generalised method of accessing system libraries. FFI is able to automatically
generate the bridge code needed to call out to some library and get the result
back into Ruby. FFI functions at runtime as real machine code generation so
that it is not necessary to have anything compiled beforehand. FFI should be
used to access the code outside of Rubinius, whether it is system libraries or
some type of extension code, for example.
There is also a specific Rubinius extension layer called Subtend. It emulates
the extension interface of Ruby to allow old Ruby extensions to work with
Rubinius.
## FFI
Module#attach_function allows a C function to be called from Ruby code using
FFI.
Module#attach_function takes the C function name, the ruby module function to
bind it to, the C argument types, and the C return type. For a list of C
argument types, see kernel/platform/ffi.rb.
Currently, FFI does not support C functions with more than 6 arguments.
When the C function will be filling in a String, be sure the Ruby String is
large enough. For the C function rbx_Digest_MD5_Finish, the digest string is
allocated with a 16 character length. The string is passed to md5_finish
which calls rbx_Digest_MD5_Finish which fills in the string with the digest.
class Digest::MD5
attach_function nil, 'rbx_Digest_MD5_Finish', :md5_finish,
[:pointer, :string], :void
def finish
digest = ' ' * 16
self.class.md5_finish @context, digest
digest
end
end
For a complete additional example, see digest/md5.rb.