public
Description: Rubinius, the Ruby VM
Homepage: http://rubini.us
Clone URL: git://github.com/evanphx/rubinius.git
evanphx (author)
Mon Jun 29 15:11:37 -0700 2009
commit  0c8637aa30c1434e7acef9e6af1b7ec00cf8fed8
tree    ccd5504314a7eb82a99d73052cde5aedf9c2282f
parent  a2debe21ecac189360ca6c48c0c03fa26bd49616
rubinius / doc / foreign_function_interface.txt
100644 52 lines (38 sloc) 2.022 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 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.