SlideShare a Scribd company logo
Extending Ruby using C++
Tristan Penman
Melbourne C++ Meetup, September 2018
Ruby essentials
What is Ruby?
 Ruby is a dynamically-typed, object-oriented language
 Garbage collection built into the VM
 Several implementations exist
 MRI – Matz's Ruby Interpreter (a.k.a. CRuby)
 JRuby – JVM based implementation
 Rubinius – Implemented in C++ and Ruby
 Ruby libraries are typically packaged as Gems
 Gems that need to use C or C++ typically do so via native
extensions
Ruby essentials
class Person
attr_reader :name, :age
def initialize(name, age) # constructor
@name, @age =name, age
end
def <=>(person) #the comparison operator for sorting
@age <=> person.age
end
def to_s #returns string representation of Person
"#{@name} (#{@age})"
end
end
Example code (1/2)
Ruby essentials
Example code (2/2)
#continued fromprevious slide
group=[
Person.new("Bob", 33),
Person.new("Chris", 16),
Person.new("Ash", 23)
]
puts group.sort.reverse
Bob(33)
Ash (23)
Chris(16)
Expected output:
Ruby essentials
Popular gems with native extensions
• Byebug - a debugger for Ruby, that uses Ruby's TracePoint API
for execution control and the Debug Inspector API for call
stack navigation. Written as a C extension for speed.
• nokogiri - an HTML and XML parser. Uses native libraries for
speed and ensure standards compliance.
• RMagick - bindings for the ImageMagick image manipulation
library.
• sqlite3 - bindings for the SQLite3 database engine.
Ruby essentials
Installing gems
$ gem install <gem_name>
To install the 'ffi' gem, which we'll use in the first example:
$ gem install ffi
This gem includes native extensions, so output will look like:
Fetching: ffi-1.9.25.gem (100%)
Building native extensions. Thiscould take a while...
Successfully installed ffi-1.9.25
Parsing documentation forffi-1.9.25
Installing ridocumentation forffi-1.9.25
Done installing documentation for ffi after 27 seconds
1 gem installed
Options for extending Ruby
• Foreign function interface
– Technique for accessing shared libraries that follow C-style
calling convention
• Inlined C / C++ code
– Compiles native code at runtime
• Native extensions with C and C++
– Precompiled
• All example code is available at:
https://github.com/tristanpenman/ruby-cpp-examples
Foreign function interface
require 'ffi'
module Simon
#Include ffi functionality as a 'mixin'
extend FFI::Library
#Link with libc
ffi_lib 'c'
#Define afunction that takes astring (char *) andprints it
attach_function :says, :puts, [:string ],:int
end
Simon.says 'Hello'
simon_ffi.rb
Foreign function interface
Limitations
• Generally requires that code is available as a shared library on
the user's operating system
• That library needs to export an API that follow the C-style
calling convention (__cdecl)
• Link errors may occur at runtime, rather than when a gem is
first installed
• In the simple case, 'ffi' gem defines methods as belonging to a
Ruby module
– Not appropriate for exposing C++ classes in Ruby
Inlined C / C++ code
require 'inline'
module Simon
inline(:C) do |builder|
builder.add_compile_flags'-xc++', '-lstdc++'
builder.include '<iostream>'
builder.c_singleton '
void says(const char *str) {
std::cout <<str <<std::endl;
}'
end
end
Simon.says 'Hello'
simon_inline.rb
Inlined C++ code
Limitations
• Incurs runtime compile overhead
• Semantics of RubyInline gem are a bit tricky
– Moving beyond defining individual methods becomes
much more complicated
– Best documentation for this happens to 'inline.rb' in the
RubyInline source code
Native extensions
• Address some of the limitations of FFI and inline C++ code
techniques
• Compiled prior to runtime, but they are generally subject to
rigorous runtime requirements
• Typically implemented using the Ruby C API
• Our simple example requires two files:
– simon_native.c, which contains the implementation code
– extconf.rb, to generate a Makefile
• simon_native.c must include Init_simon_native(), which is
called by the Ruby VM to load the extension
Native extensions
#include <ruby.h>
#include <stdio.h>
VALUE says(VALUE _self, VALUE str) {
Check_Type(str, T_STRING);
puts(StringValueCStr(str));
return Qnil;
}
voidInit_simon_native() {
VALUE mod=rb_define_module("Simon");
const intnum_args =1;
rb_define_module_function(mod, "says", says, num_args);
}
simon_native.c
Native extensions
require 'mkmf'
#Generates aMakefile tocompile simon_native.c intoa bundle
#that can be loaded intoa Ruby VM
create_makefile 'simon_native'
extconf.rb
Running 'make' should generate a bundle that can be loaded into
your Ruby program like so:
require './simon_native'
Simon.says 'Hello'
Hello
Native extensions
Limitations
• Requires code to be written in C
– Assumptions around considerations such as file extensions
• Uses Ruby C API, which is not terribly user friendly
• What about C++?
Native extensions with C++
Using the 'rice' gem
• Rice is a C++ wrapper for Ruby's C API
• Provides classes and templates that make the Ruby API easier
and safer to use
• Also provides template functions that can take an existing C++
class and make it available to Ruby code
• Minor changes to extconf.rb are required
Native extensions with C++
simon_native_rice.cpp
#include <iostream>
#include "rice/Module.hpp"
using namespace Rice;
void says(const char *str) {
std::cout <<str << std::endl;
}
extern "C"
voidInit_simon_native_rice() {
define_module("Simon")
.define_module_function("says", &says);
}
Native extensions with C++
extconf.rb
require 'mkmf-rice'
#Assumes the presence ofa file named 'simon_native_rice.cpp'
create_makefile 'simon_native_rice'
Native extensions with C++
Wrapping C++ classes
• Say we have an existing C++ class that we want to make
accessible via Ruby
• Declared in simon.hpp:
#pragmaonce
#include <iostream>
class Simon {
void says(const char * str) {
std::cout <<str << std::endl;
}
}
Wrapping C++ classes
simon_native_rice_wrapper.cpp
#include "rice/Constructor.hpp"
#include "rice/Data_Type.hpp"
#include "simon.hpp"
using namespace Rice;
extern "C"
voidInit_simon_native_rice_wrapper() {
Data_Type<Simon> rb_cSimon =
define_class<Simon>("Simon")
.define_constructor(Constructor<Simon>())
.define_method("says", &Simon::says);
}
Native extensions with C++
extconf.rb
require 'mkmf-rice' #instead of'mkmf'
create_makefile 'simon_native_rice_wrapper'
require './simon_native_rice_wrapper'
simon =Simon.new
simon.says 'Hello'
After running 'make', usage is similar to the example for the
'RubyInline' gem:
Resources
• Core documentation:
https://ruby-doc.org/core-
2.3.3/doc/extension_rdoc.html
(Beware the version number in this link)
• Aaron Bedra's Extending Ruby guide
http://aaronbedra.com/extending-ruby
• Pat Shaughnessy’s book:
Ruby Under a Microscope
Resources
• IBM's Building Ruby extensions in C++ using Rice
https://www.ibm.com/developerworks/library/os-
extendruby/index.html
• Chris Lalancette's in-depth series on writing Ruby extensions
in C, which covers numerous topics:
http://clalance.blogspot.com/2011/01/writing-ruby-
extensions-in-c-part-1.html
Thanks for listening

More Related Content

What's hot

Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜
Shengyou Fan
 
Inheritance and Polymorphism
Inheritance and PolymorphismInheritance and Polymorphism
Inheritance and Polymorphism
BG Java EE Course
 
DB1 Unidad 8: Replicación
DB1 Unidad 8: ReplicaciónDB1 Unidad 8: Replicación
DB1 Unidad 8: Replicación
Franklin Parrales Bravo
 
Function overloading ppt
Function overloading pptFunction overloading ppt
Function overloading ppt
Prof. Dr. K. Adisesha
 
Perl
PerlPerl
Introduction to Java 11
Introduction to Java 11 Introduction to Java 11
Introduction to Java 11
Knoldus Inc.
 
Generics C#
Generics C#Generics C#
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
Kuntal Bhowmick
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
Justin Lin
 
Dynamic method dispatch
Dynamic method dispatchDynamic method dispatch
Dynamic method dispatch
yugandhar vadlamudi
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
Mindfire Solutions
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
WebStackAcademy
 
Comandos ddl y dml
Comandos ddl y dmlComandos ddl y dml
Comandos ddl y dml
Gerardo
 
JRE , JDK and platform independent nature of JAVA
JRE , JDK and platform independent nature of JAVAJRE , JDK and platform independent nature of JAVA
JRE , JDK and platform independent nature of JAVA
Mehak Tawakley
 
POO Programación Orientada a Objetos
POO Programación Orientada a ObjetosPOO Programación Orientada a Objetos
POO Programación Orientada a Objetos
Luis Berganza
 
Architecture-of-Linux-operating-system.docx
Architecture-of-Linux-operating-system.docxArchitecture-of-Linux-operating-system.docx
Architecture-of-Linux-operating-system.docx
VivekGupta920049
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals I
Nick Buytaert
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
Ashwin Kumar
 
c# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventionsc# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventions
Micheal Ogundero
 
Using subqueries to solve queries
Using subqueries to solve queriesUsing subqueries to solve queries
Using subqueries to solve queries
Syed Zaid Irshad
 

What's hot (20)

Composer 經典食譜
Composer 經典食譜Composer 經典食譜
Composer 經典食譜
 
Inheritance and Polymorphism
Inheritance and PolymorphismInheritance and Polymorphism
Inheritance and Polymorphism
 
DB1 Unidad 8: Replicación
DB1 Unidad 8: ReplicaciónDB1 Unidad 8: Replicación
DB1 Unidad 8: Replicación
 
Function overloading ppt
Function overloading pptFunction overloading ppt
Function overloading ppt
 
Perl
PerlPerl
Perl
 
Introduction to Java 11
Introduction to Java 11 Introduction to Java 11
Introduction to Java 11
 
Generics C#
Generics C#Generics C#
Generics C#
 
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
Multiple Choice Questions on JAVA (object oriented programming) bank 2 -- bas...
 
Ch12 Spring 起步走
Ch12 Spring 起步走Ch12 Spring 起步走
Ch12 Spring 起步走
 
Dynamic method dispatch
Dynamic method dispatchDynamic method dispatch
Dynamic method dispatch
 
Oops in PHP
Oops in PHPOops in PHP
Oops in PHP
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
 
Comandos ddl y dml
Comandos ddl y dmlComandos ddl y dml
Comandos ddl y dml
 
JRE , JDK and platform independent nature of JAVA
JRE , JDK and platform independent nature of JAVAJRE , JDK and platform independent nature of JAVA
JRE , JDK and platform independent nature of JAVA
 
POO Programación Orientada a Objetos
POO Programación Orientada a ObjetosPOO Programación Orientada a Objetos
POO Programación Orientada a Objetos
 
Architecture-of-Linux-operating-system.docx
Architecture-of-Linux-operating-system.docxArchitecture-of-Linux-operating-system.docx
Architecture-of-Linux-operating-system.docx
 
PL/SQL Fundamentals I
PL/SQL Fundamentals IPL/SQL Fundamentals I
PL/SQL Fundamentals I
 
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
48742447 11g-sql-fundamentals-ii-additional-practices-and-solutions
 
c# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventionsc# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventions
 
Using subqueries to solve queries
Using subqueries to solve queriesUsing subqueries to solve queries
Using subqueries to solve queries
 

Similar to Extending Ruby using C++

Writing a Gem with native extensions
Writing a Gem with native extensionsWriting a Gem with native extensions
Writing a Gem with native extensions
Tristan Penman
 
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
rivierarb
 
Introduction to Ruby Native Extensions and Foreign Function Interface
Introduction to Ruby Native Extensions and Foreign Function InterfaceIntroduction to Ruby Native Extensions and Foreign Function Interface
Introduction to Ruby Native Extensions and Foreign Function Interface
Oleksii Sukhovii
 
ruby-cocoa
ruby-cocoaruby-cocoa
ruby-cocoa
tutorialsruby
 
ruby-cocoa
ruby-cocoaruby-cocoa
ruby-cocoa
tutorialsruby
 
Mac ruby deployment
Mac ruby deploymentMac ruby deployment
Mac ruby deployment
Thilo Utke
 
C#.NET
C#.NETC#.NET
C#.NET
gurchet
 
Abhishek lingineni
Abhishek lingineniAbhishek lingineni
Abhishek lingineni
abhishekl404
 
CPlusPus
CPlusPusCPlusPus
CPlusPus
rasen58
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
Dikshithkumar10
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
EPORI
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
JayarAlejo
 
C++ programming: Basic introduction to C++.ppt
C++ programming: Basic introduction to C++.pptC++ programming: Basic introduction to C++.ppt
C++ programming: Basic introduction to C++.ppt
yp02
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
JayarAlejo
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
Infotech27
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
TeacherOnat
 
Ruby Meets Cocoa
Ruby Meets CocoaRuby Meets Cocoa
Ruby Meets Cocoa
Robbert
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPL
Mario-Leander Reimer
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventure
QAware GmbH
 
Binding Objective-C Libraries, Miguel de Icaza
Binding Objective-C Libraries, Miguel de IcazaBinding Objective-C Libraries, Miguel de Icaza
Binding Objective-C Libraries, Miguel de Icaza
Xamarin
 

Similar to Extending Ruby using C++ (20)

Writing a Gem with native extensions
Writing a Gem with native extensionsWriting a Gem with native extensions
Writing a Gem with native extensions
 
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012Ruby C extensions at the Ruby drink-up of Sophia, April 2012
Ruby C extensions at the Ruby drink-up of Sophia, April 2012
 
Introduction to Ruby Native Extensions and Foreign Function Interface
Introduction to Ruby Native Extensions and Foreign Function InterfaceIntroduction to Ruby Native Extensions and Foreign Function Interface
Introduction to Ruby Native Extensions and Foreign Function Interface
 
ruby-cocoa
ruby-cocoaruby-cocoa
ruby-cocoa
 
ruby-cocoa
ruby-cocoaruby-cocoa
ruby-cocoa
 
Mac ruby deployment
Mac ruby deploymentMac ruby deployment
Mac ruby deployment
 
C#.NET
C#.NETC#.NET
C#.NET
 
Abhishek lingineni
Abhishek lingineniAbhishek lingineni
Abhishek lingineni
 
CPlusPus
CPlusPusCPlusPus
CPlusPus
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
C++ programming: Basic introduction to C++.ppt
C++ programming: Basic introduction to C++.pptC++ programming: Basic introduction to C++.ppt
C++ programming: Basic introduction to C++.ppt
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
C++_programs.ppt
C++_programs.pptC++_programs.ppt
C++_programs.ppt
 
Ruby Meets Cocoa
Ruby Meets CocoaRuby Meets Cocoa
Ruby Meets Cocoa
 
Everything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPLEverything-as-code. A polyglot adventure. #DevoxxPL
Everything-as-code. A polyglot adventure. #DevoxxPL
 
Everything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventureEverything-as-code - A polyglot adventure
Everything-as-code - A polyglot adventure
 
Binding Objective-C Libraries, Miguel de Icaza
Binding Objective-C Libraries, Miguel de IcazaBinding Objective-C Libraries, Miguel de Icaza
Binding Objective-C Libraries, Miguel de Icaza
 

Recently uploaded

Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
Ayan Halder
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Envertis Software Solutions
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
lorraineandreiamcidl
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
Yara Milbes
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
Green Software Development
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
Remote DBA Services
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
ToXSL Technologies
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
TheSMSPoint
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
Peter Muessig
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
GohKiangHock
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
ICS
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
rodomar2
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 

Recently uploaded (20)

Requirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional SafetyRequirement Traceability in Xen Functional Safety
Requirement Traceability in Xen Functional Safety
 
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative AnalysisOdoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
Odoo ERP Vs. Traditional ERP Systems – A Comparative Analysis
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOMLORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
LORRAINE ANDREI_LEQUIGAN_HOW TO USE ZOOM
 
SMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API ServiceSMS API Integration in Saudi Arabia| Best SMS API Service
SMS API Integration in Saudi Arabia| Best SMS API Service
 
GreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-JurisicGreenCode-A-VSCode-Plugin--Dario-Jurisic
GreenCode-A-VSCode-Plugin--Dario-Jurisic
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Oracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptxOracle 23c New Features For DBAs and Developers.pptx
Oracle 23c New Features For DBAs and Developers.pptx
 
Vitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdfVitthal Shirke Java Microservices Resume.pdf
Vitthal Shirke Java Microservices Resume.pdf
 
How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?How Can Hiring A Mobile App Development Company Help Your Business Grow?
How Can Hiring A Mobile App Development Company Help Your Business Grow?
 
Transform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR SolutionsTransform Your Communication with Cloud-Based IVR Solutions
Transform Your Communication with Cloud-Based IVR Solutions
 
UI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design SystemUI5con 2024 - Bring Your Own Design System
UI5con 2024 - Bring Your Own Design System
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
SQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure MalaysiaSQL Accounting Software Brochure Malaysia
SQL Accounting Software Brochure Malaysia
 
Webinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for EmbeddedWebinar On-Demand: Using Flutter for Embedded
Webinar On-Demand: Using Flutter for Embedded
 
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CDKuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
KuberTENes Birthday Bash Guadalajara - Introducción a Argo CD
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 

Extending Ruby using C++

  • 1. Extending Ruby using C++ Tristan Penman Melbourne C++ Meetup, September 2018
  • 2. Ruby essentials What is Ruby?  Ruby is a dynamically-typed, object-oriented language  Garbage collection built into the VM  Several implementations exist  MRI – Matz's Ruby Interpreter (a.k.a. CRuby)  JRuby – JVM based implementation  Rubinius – Implemented in C++ and Ruby  Ruby libraries are typically packaged as Gems  Gems that need to use C or C++ typically do so via native extensions
  • 3. Ruby essentials class Person attr_reader :name, :age def initialize(name, age) # constructor @name, @age =name, age end def <=>(person) #the comparison operator for sorting @age <=> person.age end def to_s #returns string representation of Person "#{@name} (#{@age})" end end Example code (1/2)
  • 4. Ruby essentials Example code (2/2) #continued fromprevious slide group=[ Person.new("Bob", 33), Person.new("Chris", 16), Person.new("Ash", 23) ] puts group.sort.reverse Bob(33) Ash (23) Chris(16) Expected output:
  • 5. Ruby essentials Popular gems with native extensions • Byebug - a debugger for Ruby, that uses Ruby's TracePoint API for execution control and the Debug Inspector API for call stack navigation. Written as a C extension for speed. • nokogiri - an HTML and XML parser. Uses native libraries for speed and ensure standards compliance. • RMagick - bindings for the ImageMagick image manipulation library. • sqlite3 - bindings for the SQLite3 database engine.
  • 6. Ruby essentials Installing gems $ gem install <gem_name> To install the 'ffi' gem, which we'll use in the first example: $ gem install ffi This gem includes native extensions, so output will look like: Fetching: ffi-1.9.25.gem (100%) Building native extensions. Thiscould take a while... Successfully installed ffi-1.9.25 Parsing documentation forffi-1.9.25 Installing ridocumentation forffi-1.9.25 Done installing documentation for ffi after 27 seconds 1 gem installed
  • 7. Options for extending Ruby • Foreign function interface – Technique for accessing shared libraries that follow C-style calling convention • Inlined C / C++ code – Compiles native code at runtime • Native extensions with C and C++ – Precompiled • All example code is available at: https://github.com/tristanpenman/ruby-cpp-examples
  • 8. Foreign function interface require 'ffi' module Simon #Include ffi functionality as a 'mixin' extend FFI::Library #Link with libc ffi_lib 'c' #Define afunction that takes astring (char *) andprints it attach_function :says, :puts, [:string ],:int end Simon.says 'Hello' simon_ffi.rb
  • 9. Foreign function interface Limitations • Generally requires that code is available as a shared library on the user's operating system • That library needs to export an API that follow the C-style calling convention (__cdecl) • Link errors may occur at runtime, rather than when a gem is first installed • In the simple case, 'ffi' gem defines methods as belonging to a Ruby module – Not appropriate for exposing C++ classes in Ruby
  • 10. Inlined C / C++ code require 'inline' module Simon inline(:C) do |builder| builder.add_compile_flags'-xc++', '-lstdc++' builder.include '<iostream>' builder.c_singleton ' void says(const char *str) { std::cout <<str <<std::endl; }' end end Simon.says 'Hello' simon_inline.rb
  • 11. Inlined C++ code Limitations • Incurs runtime compile overhead • Semantics of RubyInline gem are a bit tricky – Moving beyond defining individual methods becomes much more complicated – Best documentation for this happens to 'inline.rb' in the RubyInline source code
  • 12. Native extensions • Address some of the limitations of FFI and inline C++ code techniques • Compiled prior to runtime, but they are generally subject to rigorous runtime requirements • Typically implemented using the Ruby C API • Our simple example requires two files: – simon_native.c, which contains the implementation code – extconf.rb, to generate a Makefile • simon_native.c must include Init_simon_native(), which is called by the Ruby VM to load the extension
  • 13. Native extensions #include <ruby.h> #include <stdio.h> VALUE says(VALUE _self, VALUE str) { Check_Type(str, T_STRING); puts(StringValueCStr(str)); return Qnil; } voidInit_simon_native() { VALUE mod=rb_define_module("Simon"); const intnum_args =1; rb_define_module_function(mod, "says", says, num_args); } simon_native.c
  • 14. Native extensions require 'mkmf' #Generates aMakefile tocompile simon_native.c intoa bundle #that can be loaded intoa Ruby VM create_makefile 'simon_native' extconf.rb Running 'make' should generate a bundle that can be loaded into your Ruby program like so: require './simon_native' Simon.says 'Hello' Hello
  • 15. Native extensions Limitations • Requires code to be written in C – Assumptions around considerations such as file extensions • Uses Ruby C API, which is not terribly user friendly • What about C++?
  • 16. Native extensions with C++ Using the 'rice' gem • Rice is a C++ wrapper for Ruby's C API • Provides classes and templates that make the Ruby API easier and safer to use • Also provides template functions that can take an existing C++ class and make it available to Ruby code • Minor changes to extconf.rb are required
  • 17. Native extensions with C++ simon_native_rice.cpp #include <iostream> #include "rice/Module.hpp" using namespace Rice; void says(const char *str) { std::cout <<str << std::endl; } extern "C" voidInit_simon_native_rice() { define_module("Simon") .define_module_function("says", &says); }
  • 18. Native extensions with C++ extconf.rb require 'mkmf-rice' #Assumes the presence ofa file named 'simon_native_rice.cpp' create_makefile 'simon_native_rice'
  • 19. Native extensions with C++ Wrapping C++ classes • Say we have an existing C++ class that we want to make accessible via Ruby • Declared in simon.hpp: #pragmaonce #include <iostream> class Simon { void says(const char * str) { std::cout <<str << std::endl; } }
  • 20. Wrapping C++ classes simon_native_rice_wrapper.cpp #include "rice/Constructor.hpp" #include "rice/Data_Type.hpp" #include "simon.hpp" using namespace Rice; extern "C" voidInit_simon_native_rice_wrapper() { Data_Type<Simon> rb_cSimon = define_class<Simon>("Simon") .define_constructor(Constructor<Simon>()) .define_method("says", &Simon::says); }
  • 21. Native extensions with C++ extconf.rb require 'mkmf-rice' #instead of'mkmf' create_makefile 'simon_native_rice_wrapper' require './simon_native_rice_wrapper' simon =Simon.new simon.says 'Hello' After running 'make', usage is similar to the example for the 'RubyInline' gem:
  • 22. Resources • Core documentation: https://ruby-doc.org/core- 2.3.3/doc/extension_rdoc.html (Beware the version number in this link) • Aaron Bedra's Extending Ruby guide http://aaronbedra.com/extending-ruby • Pat Shaughnessy’s book: Ruby Under a Microscope
  • 23. Resources • IBM's Building Ruby extensions in C++ using Rice https://www.ibm.com/developerworks/library/os- extendruby/index.html • Chris Lalancette's in-depth series on writing Ruby extensions in C, which covers numerous topics: http://clalance.blogspot.com/2011/01/writing-ruby- extensions-in-c-part-1.html