SlideShare une entreprise Scribd logo
1  sur  35
C extensions easy in Ruby




                                       Apr 17th 2012
                                       Muriel Salvan
                  Open Source Lead developer and architect
                                       X-Aeon Solutions
                                         http://x-aeon.com
Why Ruby and C ?
Ruby without C
C without Ruby
Ruby and C combined
Ruby and C are
                   already coupled
Ruby core: around 100 classes written in
 C (String, Rational, Marshal, IO...)
Ruby standard libs: 35 libs written in C:
 (BigDecimal, Date, OpenSSL...)
Now You can write your
own C extensions easily
What is a C extension ?


A requirable library from Ruby code ...
 require 'myext'

… that can use any other Ruby's object
 or library,
… written in C,
… and compiled.
Technically speaking


A C extension is a compiled library (.so
 or .dll) that:
defines 1 specific C function,
is accessible in Ruby's load path (same
  as other .rb files)
It is used the same way Ruby's libraries
   (.rb) are (packaging, search path,
   require...)
What do you need to
             write C extensions ?

A C development environment ([g]cc, ld,
 [g]make...)
  Already installed on *nix
  Cygwin, MinGW, Ruby DevKit on Windows
Little C knowledge
Some Ruby's C API knowledge
How to write your C
    extension
Default Ruby program
            structure
myapp/
  bin/
    exec.rb
  lib/
    myapp/
       mylib.rb
  ext/
    myapp/
       myext.c
       extconf.rb
       myotherlib/
         otherlib.c
         extconf.rb
Write the C file
               ext/myapp/myext.c


#include "ruby.h"


void Init_myext() {
    printf("Hello Ruby from C!n");
}
Write the extconf file
              ext/myapp/extconf.rb


require 'mkmf'
create_makefile('myext')


And that's it!
Your C extension is ready to be compiled
 and used
How to compile and use
  your C extension
Compile it
                              in ext/myapp/
=> ruby extconf.rb
creating Makefile

          => ext/myapp/Makefile
=> make
gcc -I. -I/usr/lib/ruby/1.8/i386-cygwin
  -I/usr/lib/ruby/1.8/i386-cygwin -I.   -g -O2    -c
  myext.c
gcc -shared -s -o myext.so myext.o -L. -L/usr/lib -L.
  -Wl,--enable-auto-image-base,--enable-auto-import,--
  export-all   -lruby -ldl -lcrypt

          => ext/myapp/myext.so
Use it
                               bin/exec.rb
#!/bin/env ruby
puts 'Before requiring C extension'
require 'myapp/myext'
puts 'After requiring C extension'

=> ruby -Iext bin/exec.rb
Before requiring C extension
Hello Ruby from C!
After requiring C extension
And now, package it in a
    nice Ruby gem!
First flavor:
          Package the compiled
                      extension
Add the compiled extension to the files
 list (like any other library)
Add your ext/ directory as a required
 path
Don't forget to set your Gem platform as
 specific!
Platform dependent:
                              gem spec
                      myapp.compiled.gemspec.rb
Gem::Specification.new do |spec|
  spec.name = 'my_app_compiled'
  spec.version = '0.1'
  spec.summary = 'Summary'
  spec.author = 'me'
  spec.bindir = 'bin'
  spec.executable = 'exec.rb'
  spec.files = [ 'bin/exec.rb',
  'ext/myapp/myext.so' ]
  spec.platform = Gem::Platform::CURRENT
  spec.require_path = 'ext'
end
=> gem build myapp.compiled.gemspec.rb
  Successfully built RubyGem
  Name: my_app_compiled
  Version: 0.1
  File: my_app_compiled-0.1-x86-cygwin.gem
Platform dependent:
                 Install and run it
=> gem install my_app_compiled-0.1-x86-
  cygwin.gem
Successfully installed my_app_compiled-0.1-
  x86-cygwin
1 gem installed
Installing ri documentation for
  my_app_compiled-0.1-x86-cygwin...
Installing RDoc documentation for
  my_app_compiled-0.1-x86-cygwin...

=> exec.rb
Before requiring C extension
Hello Ruby from C!
After requiring C extension
Second flavor:
          Platform independent
                     packaging
Add the C extension source files to the
 files list
Add your ext/ directory as a required
 path
Keep your Gem platform as Ruby
Register the C extension (path to the
 extconf.rb file)
Platform independent:
                           gem spec
                    myapp.gemspec.rb
Gem::Specification.new do |spec|
  spec.name = 'my_app'
  # { ... }
  spec.executable = 'exec.rb'
   spec.files = [ 'bin/exec.rb',
   'ext/myapp/myext.c', 'ext/myapp/extconf.rb'
   ]
   spec.platform = Gem::Platform::RUBY
   spec.require_path = 'ext'
   spec.extensions =
   [ 'ext/myapp/extconf.rb' ]
end gem build myapp.gemspec.rb
=>
   Successfully built RubyGem
   Name: my_app
   Version: 0.1
   File: my_app-0.1.gem
Platform independent:
                Install and run it
=> gem install my_app-0.1.gem
Building native extensions. This could take
  a while...
Successfully installed my_app-0.1
1 gem installed
Installing ri documentation for my_app-0.1...
Installing RDoc documentation for
  my_app-0.1...

=> exec.rb
Before requiring C extension
Hello Ruby from C!
After requiring C extension
Which flavor the best ?

Platform dependent:   Platform independent:
Need to release 1     Need to release just 1
 Ruby gem per          Ruby gem
 platform (need to    Users must have a C
 compile on each       development
 platform)             environment to
Users do not need      install it
 any development
 environment
Need more than a Hello
      World ?
  => The Ruby C API
module MyModule
                  class MyClass
                    def my_method(param1, param2,
                  param3)
                    end
                  end
                end

static VALUE myclass_mymethod(
  VALUE rb_self,
  VALUE rb_param1,
  VALUE rb_param2,
  VALUE rb_param3) {
}

void Init_myext() {
  VALUE mymodule = rb_define_module("MyModule");
  VALUE myclass = rb_define_class_under(mymodule,
  "MyClass", rb_cObject);
  rb_define_method(myclass, "my_method",
  myclass_mymethod, 3);
}
if param1 == nil
                              puts 'Param1 is nil'
                              return nil
                            else
                              return param1 + 42
                            end




if (rb_param1 == Qnil) {
  rb_funcall(rb_self, rb_intern("puts"), 1,
  rb_str_new2("Param1 is nil"));
  return Qnil;
} else {
  int param1 = FIX2INT(rb_param1);
  VALUE result = INT2FIX(param1 + 42);
  return result;
}
param2.each do |elem|
                               elemstr = elem.to_s
                               elemstr[0] = 'A'
                               puts elemstr[0..3]
                             end



int nbrelems = RARRAY(rb_param2)->len;
int idx;
for (idx = 0; idx < nbrelems; ++idx) {
  VALUE rb_elem = rb_ary_entry(rb_param2, idx);
  VALUE rb_elemstr = rb_funcall(rb_elem,
  rb_intern("to_s"), 0);
  char* elemstr = RSTRING_PTR(rb_elemstr);
  elemstr[0] = 'A';
  char* substr = (char*)malloc(5);
  strncpy(substr, elemstr, 4);
  substr[4] = '0';
  rb_funcall(rb_self, rb_intern("puts"), 1,
  rb_str_new2(substr));
  free(substr);
}
param3.block_method(3) do |
                          block_param|
                          puts param1 + block_param
                        end


static VALUE call_block_method(VALUE rb_params) {
  VALUE rb_object = rb_ary_entry(rb_params, 0);
  VALUE rb_value = rb_ary_entry(rb_params, 1);
  return rb_funcall(rb_object, rb_intern("block_method"), 1, rb_value);
}

static VALUE yielded_block(VALUE rb_yield_params, VALUE
   rb_iterate_params) {
  VALUE rb_block_param = rb_yield_params;
  VALUE rb_self = rb_ary_entry(rb_iterate_params, 0);
  VALUE rb_param1 = rb_ary_entry(rb_iterate_params, 1);
  return rb_funcall(rb_self, rb_intern("puts"), 1,
   INT2FIX(FIX2INT(rb_block_param)+FIX2INT(rb_param1)));
}

rb_iterate(
  call_block_method,
  rb_ary_new3(2, rb_param3, INT2FIX(3)),
  yielded_block,
  rb_ary_new3(2, rb_self, rb_param1)
);
                                  Thanks Matz for Ruby!
Using external compiled
       libraries
      => FFI gem
FFI gem

 Import external functions from a
compiled library into a Ruby module

  require 'ffi'

  module MyLib
    extend FFI::Library
    ffi_lib 'c'
    attach_function :puts, [ :string ], :int
  end

  MyLib.puts 'Hello, World using libc!'
FFI features

It has a very intuitive DSL
It supports all C native types
It supports C structs (also nested),
   enums and global variables
It supports callbacks
It has smart methods to handle memory
   management of pointers and structs
Links

          Makefile generation options:
          Linuxtopia tutorial
          mkmf rdoc
          Ruby C API:
          Eqqon article
          Matz' Readme
          Metaprogramming
          FFI gem

This presentation is available under CC-BY license by Muriel Salvan
Q/A

Contenu connexe

Tendances

Polymorphism In Java
Polymorphism In JavaPolymorphism In Java
Polymorphism In JavaSpotle.ai
 
Software Testing Strategies
Software Testing StrategiesSoftware Testing Strategies
Software Testing StrategiesAlpana Bhaskar
 
Architecture Design in Software Engineering
Architecture Design in Software EngineeringArchitecture Design in Software Engineering
Architecture Design in Software Engineeringcricket2ime
 
Python Exception Handling
Python Exception HandlingPython Exception Handling
Python Exception HandlingMegha V
 
Applet and graphics programming
Applet and graphics programmingApplet and graphics programming
Applet and graphics programmingmcanotes
 
Slice Based testing and Object Oriented Testing
Slice Based testing and Object Oriented TestingSlice Based testing and Object Oriented Testing
Slice Based testing and Object Oriented Testingvarsha sharma
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageAnıl Sözeri
 
Java Collection framework
Java Collection frameworkJava Collection framework
Java Collection frameworkankitgarg_er
 
What is Ad-Hoc Testing
What is Ad-Hoc TestingWhat is Ad-Hoc Testing
What is Ad-Hoc TestingExforsys Inc
 
Python Programming | JNTUA | UNIT 2 | Fruitful Functions |
Python Programming | JNTUA | UNIT 2 | Fruitful Functions | Python Programming | JNTUA | UNIT 2 | Fruitful Functions |
Python Programming | JNTUA | UNIT 2 | Fruitful Functions | FabMinds
 
Exception Handling
Exception HandlingException Handling
Exception HandlingReddhi Basu
 
An Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysAn Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysMartin Chapman
 

Tendances (20)

C#.NET
C#.NETC#.NET
C#.NET
 
Inheritance and Polymorphism
Inheritance and PolymorphismInheritance and Polymorphism
Inheritance and Polymorphism
 
Polymorphism In Java
Polymorphism In JavaPolymorphism In Java
Polymorphism In Java
 
Java
JavaJava
Java
 
Software Testing Strategies
Software Testing StrategiesSoftware Testing Strategies
Software Testing Strategies
 
Architecture Design in Software Engineering
Architecture Design in Software EngineeringArchitecture Design in Software Engineering
Architecture Design in Software Engineering
 
Python Exception Handling
Python Exception HandlingPython Exception Handling
Python Exception Handling
 
Code coverage
Code coverageCode coverage
Code coverage
 
Applet and graphics programming
Applet and graphics programmingApplet and graphics programming
Applet and graphics programming
 
Swift Introduction
Swift IntroductionSwift Introduction
Swift Introduction
 
Slice Based testing and Object Oriented Testing
Slice Based testing and Object Oriented TestingSlice Based testing and Object Oriented Testing
Slice Based testing and Object Oriented Testing
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Java Collection framework
Java Collection frameworkJava Collection framework
Java Collection framework
 
What is Ad-Hoc Testing
What is Ad-Hoc TestingWhat is Ad-Hoc Testing
What is Ad-Hoc Testing
 
Cgi
CgiCgi
Cgi
 
Python Programming | JNTUA | UNIT 2 | Fruitful Functions |
Python Programming | JNTUA | UNIT 2 | Fruitful Functions | Python Programming | JNTUA | UNIT 2 | Fruitful Functions |
Python Programming | JNTUA | UNIT 2 | Fruitful Functions |
 
Software testing
Software testingSoftware testing
Software testing
 
Core Java Tutorial
Core Java TutorialCore Java Tutorial
Core Java Tutorial
 
Exception Handling
Exception HandlingException Handling
Exception Handling
 
An Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: ArraysAn Introduction to Programming in Java: Arrays
An Introduction to Programming in Java: Arrays
 

En vedette

Ruby and Docker on Rails
Ruby and Docker on RailsRuby and Docker on Rails
Ruby and Docker on RailsMuriel Salvan
 
Pry at the Ruby Drink-up of Sophia, February 2012
Pry at the Ruby Drink-up of Sophia, February 2012Pry at the Ruby Drink-up of Sophia, February 2012
Pry at the Ruby Drink-up of Sophia, February 2012rivierarb
 
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013rivierarb
 
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013Ruby and Twitter at the Ruby drink-up of Sophia, January 2013
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013rivierarb
 
Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013rivierarb
 
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012rivierarb
 
DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011rivierarb
 
Quines—Programming your way back to where you were
Quines—Programming your way back to where you wereQuines—Programming your way back to where you were
Quines—Programming your way back to where you wereJean-Baptiste Mazon
 
The Dark Side of Programming Languages
The Dark Side of Programming LanguagesThe Dark Side of Programming Languages
The Dark Side of Programming LanguagesJean-Baptiste Mazon
 

En vedette (10)

Ruby and Docker on Rails
Ruby and Docker on RailsRuby and Docker on Rails
Ruby and Docker on Rails
 
Pry at the Ruby Drink-up of Sophia, February 2012
Pry at the Ruby Drink-up of Sophia, February 2012Pry at the Ruby Drink-up of Sophia, February 2012
Pry at the Ruby Drink-up of Sophia, February 2012
 
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
Ruby 2.0 at the Ruby drink-up of Sophia, February 2013
 
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013Ruby and Twitter at the Ruby drink-up of Sophia, January 2013
Ruby and Twitter at the Ruby drink-up of Sophia, January 2013
 
Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013Ruby object model at the Ruby drink-up of Sophia, January 2013
Ruby object model at the Ruby drink-up of Sophia, January 2013
 
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012
Piloting processes through std IO at the Ruby Drink-up of Sophia, January 2012
 
DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011DRb at the Ruby Drink-up of Sophia, December 2011
DRb at the Ruby Drink-up of Sophia, December 2011
 
Untitled talk at Riviera.rb
Untitled talk at Riviera.rbUntitled talk at Riviera.rb
Untitled talk at Riviera.rb
 
Quines—Programming your way back to where you were
Quines—Programming your way back to where you wereQuines—Programming your way back to where you were
Quines—Programming your way back to where you were
 
The Dark Side of Programming Languages
The Dark Side of Programming LanguagesThe Dark Side of Programming Languages
The Dark Side of Programming Languages
 

Similaire à Ruby C extensions at the Ruby drink-up of Sophia, April 2012

Writing a Gem with native extensions
Writing a Gem with native extensionsWriting a Gem with native extensions
Writing a Gem with native extensionsTristan Penman
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortegaarman o
 
Mac ruby deployment
Mac ruby deploymentMac ruby deployment
Mac ruby deploymentThilo Utke
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby TeamArto Artnik
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发shaokun
 
Extending Ruby using C++
Extending Ruby using C++Extending Ruby using C++
Extending Ruby using C++Tristan Penman
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Halil Kaya
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725miguel dominguez
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Yevgeniy Brikman
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725MortazaJohari
 
What lies beneath the beautiful code?
What lies beneath the beautiful code?What lies beneath the beautiful code?
What lies beneath the beautiful code?Niranjan Sarade
 
#CNX14 - Using Ruby for Reliability, Consistency, and Speed
#CNX14 - Using Ruby for Reliability, Consistency, and Speed#CNX14 - Using Ruby for Reliability, Consistency, and Speed
#CNX14 - Using Ruby for Reliability, Consistency, and SpeedSalesforce Marketing Cloud
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Racksickill
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mrubyHiroshi SHIBATA
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular applicationmirrec
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...Matt Gauger
 

Similaire à Ruby C extensions at the Ruby drink-up of Sophia, April 2012 (20)

Writing a Gem with native extensions
Writing a Gem with native extensionsWriting a Gem with native extensions
Writing a Gem with native extensions
 
Introduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman OrtegaIntroduction to Rails - presented by Arman Ortega
Introduction to Rails - presented by Arman Ortega
 
Mac ruby deployment
Mac ruby deploymentMac ruby deployment
Mac ruby deployment
 
Toolbox of a Ruby Team
Toolbox of a Ruby TeamToolbox of a Ruby Team
Toolbox of a Ruby Team
 
Rails web api 开发
Rails web api 开发Rails web api 开发
Rails web api 开发
 
Extending Ruby using C++
Extending Ruby using C++Extending Ruby using C++
Extending Ruby using C++
 
Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36Infrastructure as code - Python Saati #36
Infrastructure as code - Python Saati #36
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
How to write Ruby extensions with Crystal
How to write Ruby extensions with CrystalHow to write Ruby extensions with Crystal
How to write Ruby extensions with Crystal
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
What lies beneath the beautiful code?
What lies beneath the beautiful code?What lies beneath the beautiful code?
What lies beneath the beautiful code?
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 
#CNX14 - Using Ruby for Reliability, Consistency, and Speed
#CNX14 - Using Ruby for Reliability, Consistency, and Speed#CNX14 - Using Ruby for Reliability, Consistency, and Speed
#CNX14 - Using Ruby for Reliability, Consistency, and Speed
 
Building web framework with Rack
Building web framework with RackBuilding web framework with Rack
Building web framework with Rack
 
Middleware as Code with mruby
Middleware as Code with mrubyMiddleware as Code with mruby
Middleware as Code with mruby
 
Intro to Rack
Intro to RackIntro to Rack
Intro to Rack
 
Rails Engine | Modular application
Rails Engine | Modular applicationRails Engine | Modular application
Rails Engine | Modular application
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 

Dernier

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesThousandEyes
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 

Dernier (20)

(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyesAssure Ecommerce and Retail Operations Uptime with ThousandEyes
Assure Ecommerce and Retail Operations Uptime with ThousandEyes
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 

Ruby C extensions at the Ruby drink-up of Sophia, April 2012

  • 1. C extensions easy in Ruby Apr 17th 2012 Muriel Salvan Open Source Lead developer and architect X-Aeon Solutions http://x-aeon.com
  • 5. Ruby and C combined
  • 6. Ruby and C are already coupled Ruby core: around 100 classes written in C (String, Rational, Marshal, IO...) Ruby standard libs: 35 libs written in C: (BigDecimal, Date, OpenSSL...)
  • 7. Now You can write your own C extensions easily
  • 8. What is a C extension ? A requirable library from Ruby code ... require 'myext' … that can use any other Ruby's object or library, … written in C, … and compiled.
  • 9. Technically speaking A C extension is a compiled library (.so or .dll) that: defines 1 specific C function, is accessible in Ruby's load path (same as other .rb files) It is used the same way Ruby's libraries (.rb) are (packaging, search path, require...)
  • 10. What do you need to write C extensions ? A C development environment ([g]cc, ld, [g]make...) Already installed on *nix Cygwin, MinGW, Ruby DevKit on Windows Little C knowledge Some Ruby's C API knowledge
  • 11. How to write your C extension
  • 12. Default Ruby program structure myapp/ bin/ exec.rb lib/ myapp/ mylib.rb ext/ myapp/ myext.c extconf.rb myotherlib/ otherlib.c extconf.rb
  • 13. Write the C file ext/myapp/myext.c #include "ruby.h" void Init_myext() { printf("Hello Ruby from C!n"); }
  • 14. Write the extconf file ext/myapp/extconf.rb require 'mkmf' create_makefile('myext') And that's it! Your C extension is ready to be compiled and used
  • 15. How to compile and use your C extension
  • 16. Compile it in ext/myapp/ => ruby extconf.rb creating Makefile => ext/myapp/Makefile => make gcc -I. -I/usr/lib/ruby/1.8/i386-cygwin -I/usr/lib/ruby/1.8/i386-cygwin -I. -g -O2 -c myext.c gcc -shared -s -o myext.so myext.o -L. -L/usr/lib -L. -Wl,--enable-auto-image-base,--enable-auto-import,-- export-all -lruby -ldl -lcrypt => ext/myapp/myext.so
  • 17. Use it bin/exec.rb #!/bin/env ruby puts 'Before requiring C extension' require 'myapp/myext' puts 'After requiring C extension' => ruby -Iext bin/exec.rb Before requiring C extension Hello Ruby from C! After requiring C extension
  • 18. And now, package it in a nice Ruby gem!
  • 19. First flavor: Package the compiled extension Add the compiled extension to the files list (like any other library) Add your ext/ directory as a required path Don't forget to set your Gem platform as specific!
  • 20. Platform dependent: gem spec myapp.compiled.gemspec.rb Gem::Specification.new do |spec| spec.name = 'my_app_compiled' spec.version = '0.1' spec.summary = 'Summary' spec.author = 'me' spec.bindir = 'bin' spec.executable = 'exec.rb' spec.files = [ 'bin/exec.rb', 'ext/myapp/myext.so' ] spec.platform = Gem::Platform::CURRENT spec.require_path = 'ext' end => gem build myapp.compiled.gemspec.rb Successfully built RubyGem Name: my_app_compiled Version: 0.1 File: my_app_compiled-0.1-x86-cygwin.gem
  • 21. Platform dependent: Install and run it => gem install my_app_compiled-0.1-x86- cygwin.gem Successfully installed my_app_compiled-0.1- x86-cygwin 1 gem installed Installing ri documentation for my_app_compiled-0.1-x86-cygwin... Installing RDoc documentation for my_app_compiled-0.1-x86-cygwin... => exec.rb Before requiring C extension Hello Ruby from C! After requiring C extension
  • 22. Second flavor: Platform independent packaging Add the C extension source files to the files list Add your ext/ directory as a required path Keep your Gem platform as Ruby Register the C extension (path to the extconf.rb file)
  • 23. Platform independent: gem spec myapp.gemspec.rb Gem::Specification.new do |spec| spec.name = 'my_app' # { ... } spec.executable = 'exec.rb' spec.files = [ 'bin/exec.rb', 'ext/myapp/myext.c', 'ext/myapp/extconf.rb' ] spec.platform = Gem::Platform::RUBY spec.require_path = 'ext' spec.extensions = [ 'ext/myapp/extconf.rb' ] end gem build myapp.gemspec.rb => Successfully built RubyGem Name: my_app Version: 0.1 File: my_app-0.1.gem
  • 24. Platform independent: Install and run it => gem install my_app-0.1.gem Building native extensions. This could take a while... Successfully installed my_app-0.1 1 gem installed Installing ri documentation for my_app-0.1... Installing RDoc documentation for my_app-0.1... => exec.rb Before requiring C extension Hello Ruby from C! After requiring C extension
  • 25. Which flavor the best ? Platform dependent: Platform independent: Need to release 1 Need to release just 1 Ruby gem per Ruby gem platform (need to Users must have a C compile on each development platform) environment to Users do not need install it any development environment
  • 26. Need more than a Hello World ? => The Ruby C API
  • 27. module MyModule class MyClass def my_method(param1, param2, param3) end end end static VALUE myclass_mymethod( VALUE rb_self, VALUE rb_param1, VALUE rb_param2, VALUE rb_param3) { } void Init_myext() { VALUE mymodule = rb_define_module("MyModule"); VALUE myclass = rb_define_class_under(mymodule, "MyClass", rb_cObject); rb_define_method(myclass, "my_method", myclass_mymethod, 3); }
  • 28. if param1 == nil puts 'Param1 is nil' return nil else return param1 + 42 end if (rb_param1 == Qnil) { rb_funcall(rb_self, rb_intern("puts"), 1, rb_str_new2("Param1 is nil")); return Qnil; } else { int param1 = FIX2INT(rb_param1); VALUE result = INT2FIX(param1 + 42); return result; }
  • 29. param2.each do |elem| elemstr = elem.to_s elemstr[0] = 'A' puts elemstr[0..3] end int nbrelems = RARRAY(rb_param2)->len; int idx; for (idx = 0; idx < nbrelems; ++idx) { VALUE rb_elem = rb_ary_entry(rb_param2, idx); VALUE rb_elemstr = rb_funcall(rb_elem, rb_intern("to_s"), 0); char* elemstr = RSTRING_PTR(rb_elemstr); elemstr[0] = 'A'; char* substr = (char*)malloc(5); strncpy(substr, elemstr, 4); substr[4] = '0'; rb_funcall(rb_self, rb_intern("puts"), 1, rb_str_new2(substr)); free(substr); }
  • 30. param3.block_method(3) do | block_param| puts param1 + block_param end static VALUE call_block_method(VALUE rb_params) { VALUE rb_object = rb_ary_entry(rb_params, 0); VALUE rb_value = rb_ary_entry(rb_params, 1); return rb_funcall(rb_object, rb_intern("block_method"), 1, rb_value); } static VALUE yielded_block(VALUE rb_yield_params, VALUE rb_iterate_params) { VALUE rb_block_param = rb_yield_params; VALUE rb_self = rb_ary_entry(rb_iterate_params, 0); VALUE rb_param1 = rb_ary_entry(rb_iterate_params, 1); return rb_funcall(rb_self, rb_intern("puts"), 1, INT2FIX(FIX2INT(rb_block_param)+FIX2INT(rb_param1))); } rb_iterate( call_block_method, rb_ary_new3(2, rb_param3, INT2FIX(3)), yielded_block, rb_ary_new3(2, rb_self, rb_param1) ); Thanks Matz for Ruby!
  • 31. Using external compiled libraries => FFI gem
  • 32. FFI gem Import external functions from a compiled library into a Ruby module require 'ffi' module MyLib extend FFI::Library ffi_lib 'c' attach_function :puts, [ :string ], :int end MyLib.puts 'Hello, World using libc!'
  • 33. FFI features It has a very intuitive DSL It supports all C native types It supports C structs (also nested), enums and global variables It supports callbacks It has smart methods to handle memory management of pointers and structs
  • 34. Links Makefile generation options: Linuxtopia tutorial mkmf rdoc Ruby C API: Eqqon article Matz' Readme Metaprogramming FFI gem This presentation is available under CC-BY license by Muriel Salvan
  • 35. Q/A