Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Developing Ruby gems with native extensions

Developing Ruby gems with native extensions

Presented at Geneva.rb on 21st January 2015

Dimiter Petrov

January 21, 2015
Tweet

More Decks by Dimiter Petrov

Other Decks in Programming

Transcript

  1. You are uncomfortable with C and there is a another

    communication channel with the underlying system (HTTP, UNIX sockets, ...) 8 / 16
  2. $ tree . ├── ext │ └── hello │ ├──

    extconf.rb │ └── hello.c └── hello.gemspec ext/hello/extconf.rb require 'mkmf' have_library('hello') create_makefile('hello/hello') ext/hello/hello.c #include <ruby.h> void Init_hello() { // ... } hello.gemspec Gem::Specification.new do |spec| # ... spec.extensions << 'ext/hello/extconf.rb' end 10 / 16
  3. $ cd ext/hello $ ruby extconf.rb checking for main() in

    -lhello... no creating Makefile $ make compiling hello.c linking shared-object hello/hello.so $ irb irb(main):001:0> require './hello' => true 11 / 16
  4. $ tree . ├── ext │ └── hello │ ├──

    extconf.rb │ └── hello.c ├── lib └── Rakefile $ rake compile ... $ ls lib/ hello.so $ irb -Ilib irb(main):001:0> require 'hello' => true Rakefile require 'rake/extensiontask' Rake::ExtensionTask.new('hello') With the rake-compiler gem 12 / 16
  5. extconf.rb Checks compilation conditions and generates a Makefile. For example:

    require 'mkmf' HEADER_DIRS = [ # ... ] LIB_DIRS = [ # ... ] unless find_header('foo/foo.h', *HEADER_DIRS) abort "libfoo is missing. Please install libfoo" end unless find_library('foo', 'foo_imported_function', *LIB_DIRS) abort "libfoo is missing. Please install libfoo" end create_makefile('foo/foo') See the MakeMakefile documentation for all available checks. 13 / 16
  6. Library initialization and entry point When the interpreter loads the

    library LIBRARY, it executes the Init_LIBRARY() function. #include <ruby.h> #include <foo.h> void Init_foo(void) { VALUE mFoo = rb_define_module("Foo"); rb_define_singleton_method(mFoo, "bar", bar, 1); //... } 14 / 16
  7. Ruby Extension API Used by the library to interact with

    the Ruby interpreter from the C code. It provides functions to: check data types convert between different types define classes, modules, constants, methods invoke Ruby methods raise exceptions handle allocations and deallocations wrap C pointers into Ruby objects etc. The documentation is in the README.EXT file that comes with the CRuby source code. 15 / 16
  8. Further reading Official documentation about making extension libraries for Ruby:

    https://github.com/ruby/ruby/blob/trunk/README.EXT Rubygems guide about gems with extensions: http://guides.rubygems.org/gems-with-extensions/ The rake-compiler gem: https://github.com/rake-compiler/rake-compiler Writing Ruby C extensions: http://tenderlovemaking.com/2009/12/18/writing-ruby-c-extensions-part- 1.html http://tenderlovemaking.com/2010/12/11/writing-ruby-c-extensions-part- 2.html Native extensions with Java: https://blog.jcoglan.com/2012/08/02/your-first-ruby-native-extension-java/ 16 / 16