SlideShare a Scribd company logo
1 of 41
Download to read offline
Native Extensions
Served 3 Ways
Tejas Dinkar

Nilenso Software
about.me
•

Hi, I’m Tejas

•

Nilenso: Partner

•

twitter: tdinkar

•

github: gja
about.talk
•

Expect to see lots of code

•

Will have about 5 minutes for questions

•

Please laugh at my jokes!

•

Will cover C Extensions, FFI and SWIG
Native Extensions
•

Integrate with new libraries

•

Improve Performance of critical code

•

Write code that works across languages

•

Feel super 1337
Let’s talk about Python

•

Pythonista’s in the house?

•

Yes, I’m trolling you!

http://montgomeryq.blogspot.in/2011/05/random-illustration-tuesday-python-ruby.html
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
#include "Python.h"
#include "ruby.h"

!

static PyObject *python_ruby_eval(PyObject *self, PyObject *string)
{
VALUE val = rb_eval_string(PyString_AsString(string));
switch(TYPE(val)) {
case T_FIXNUM: return PyInt_FromLong(FIX2INT(val));
case T_STRING: return PyString_FromString(StringValuePtr(val));
default: return Py_None; // Can handle these cases later
}
}

!

static PyMethodDef module_functions[] = {
{ "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" },
{ NULL }
};

!

void initruby(void)
{
ruby_init();
Py_InitModule3("ruby", module_functions, "A ruby module for python.");
}
Require Files?
static PyObject *python_ruby_require(PyObject *self, PyObject *file)
{
rb_require(PyString_AsString(file));
return Py_True;
}
Congrats!
Common Fears

MEMORY ALLOCATION!?
Memory Management

•

Data_Wrap_Struct(klass, mark_cb, free_cb, *data)

•

Data_Get_Struct( VALUE, data_type, data* )
Common Fears
Portability

http://geekandpoke.typepad.com/geekandpoke/2008/05/the-history-of.html
string.c
void Init_String(void) {!
rb_cString = rb_define_class("String", rb_cObject);!
// ...!
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);!
rb_define_method(rb_cString, "==", rb_str_equal, 1);!
// ...!
rb_define_method(rb_cString, "insert", rb_str_insert, 2);!
rb_define_method(rb_cString, "length", rb_str_length, 0);!
// ...!
}!
!
static VALUE rb_str_eql(VALUE self, VALUE str2)!
{!
if (self == str2) return Qtrue;!
if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;!
return str_eql(self, str2);!
}!
string.c
void Init_String(void) {!
rb_cString = rb_define_class("String", rb_cObject);!
// ...!
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);!
rb_define_method(rb_cString, "==", rb_str_equal, 1);!
// ...!
rb_define_method(rb_cString, "insert", rb_str_insert, 2);!
rb_define_method(rb_cString, "length", rb_str_length, 0);!
// ...!
}!
!
static VALUE rb_str_eql(VALUE str2, VALUE str2)!
{!
if (self == str2) return Qtrue;!
if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;!
return str_eql(self, str2);!
}!
string.c
void Init_String(void) {!
rb_cString = rb_define_class("String", rb_cObject);!
// ...!
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);!
rb_define_method(rb_cString, "==", rb_str_equal, 1);!
// ...!
rb_define_method(rb_cString, "insert", rb_str_insert, 2);!
rb_define_method(rb_cString, "length", rb_str_length, 0);!
// ...!
}!
!
static VALUE rb_str_eql(VALUE str2, VALUE str2)!
{!
if (self == str2) return Qtrue;!
if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;!
return str_eql(self, str2);!
}!
C Extensions

Native Code

Ruby Aware!
Native Code

Ruby Code
Foreign Function Interface

Native Code

Native Aware!
Ruby Code

Ruby Code
Foreign Function Interface

•

A Ruby DSL

•

Works across all Ruby Implementations

•

Converts to and from C primitives for you
example
require 'ffi'!
!

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

MyLib.puts 'Hello, World using libc!'
another example
require 'ffi'!
!

module MyMathLib!
extend FFI::Library!
ffi_lib 'm'!
attach_function :pow, [:double, :double],!
:double!
end!
!

MyMathLib.pow(4, 5) # => 1024.0
Lots of built in types
Numbers!! ! ! ! ! Character!! ! ! ! ! Other!
:int! ! ! ! ! ! ! :char!! ! ! ! ! ! ! :pointer!
:short! ! ! ! ! ! :string!
:long!
:double!
:float!
Foreign Function Interface
•

Probably your best solution

•

It’s really easy

•

Do your modelling in Ruby

•

Still have to worry about GC

•

Sadly, no C++ without wrapping
Memory in FFI

def run_query_which_will_crash!
db_connection = MyFFIModule.database_connection("localhost")!
MyFFIModule.database_query(db_connection, "select * from users")!
end!
Memory in FFI
This will get GCed
def run_query_which_will_crash!
db_connection = MyFFIModule.database_connection("localhost")!
MyFFIModule.database_query(db_connection, "select * from users")!
end!
SWIG
•

Simplified Wrapper and Interface Generator

•

Annotate your C/C++ header files

•

It generates native extensions for languages
•

About 20 languages currently supported
SWIG
Ruby Code

Magic
Native Code

Python Code
The Magic
•

Takes an interface file

•

Auto generates code to make it work

•

For ruby, it’s a `regular’ C extension

•

For python, it’s a a .c and .py file

•

For Java it’s a JNI interface

•

Still need to do your own GC
The Rectangle
class Rectangle!
{!
int length;!
int breadth;!
!

public:!
Rectangle(int length, int breadth);!
int area();!
};
The Rectangle
#ifdef SWIG
%module shape
%{

SWIG Stuff Here

class Rectangle!
{!
int length;!
int breadth;!
!

public:!
Rectangle(int length, int breadth);!
int area();!
};
%}
require 'shapes'!
!

rectangle = shapes.Rectangle.new(10, 12)!
rectangle.area == 120!
Other Options

•

DL (Dynamic Load)

•

Fiddle(r)
TL;DR
•

Native Extensions are fun and easy to build

•

The three big tools

•

You want to pick FFI if you don’t maintain the lib

•

SWIG may be better if you are a maintainer
Thank You
super integration
wow

so extension

so native

ruby = win

wow

such easy

Many Questions?
no python

such performance

More Related Content

What's hot

7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)Steven Francia
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming languageSlawomir Dorzak
 
Introduction to Programming in Go
Introduction to Programming in GoIntroduction to Programming in Go
Introduction to Programming in GoAmr Hassan
 
Learning Python from Data
Learning Python from DataLearning Python from Data
Learning Python from DataMosky Liu
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminarygo-lang
 
An Overview Of Standard C++Tr1
An Overview Of Standard C++Tr1An Overview Of Standard C++Tr1
An Overview Of Standard C++Tr1Ganesh Samarthyam
 
Beyond the Style Guides
Beyond the Style GuidesBeyond the Style Guides
Beyond the Style GuidesMosky Liu
 
Programming with Python - Basic
Programming with Python - BasicProgramming with Python - Basic
Programming with Python - BasicMosky Liu
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleSaúl Ibarra Corretgé
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...David Beazley (Dabeaz LLC)
 
Using SWIG to Control, Prototype, and Debug C Programs with Python
Using SWIG to Control, Prototype, and Debug C Programs with PythonUsing SWIG to Control, Prototype, and Debug C Programs with Python
Using SWIG to Control, Prototype, and Debug C Programs with PythonDavid Beazley (Dabeaz LLC)
 
Hourglass Interfaces for C++ APIs - CppCon 2014
Hourglass Interfaces for C++ APIs - CppCon 2014Hourglass Interfaces for C++ APIs - CppCon 2014
Hourglass Interfaces for C++ APIs - CppCon 2014Stefanus Du Toit
 
The Benefits of Type Hints
The Benefits of Type HintsThe Benefits of Type Hints
The Benefits of Type Hintsmasahitojp
 
PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimeNational Cheng Kung University
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеSergey Platonov
 
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Codemotion
 
Learn To Test Like A Grumpy Programmer - 3 hour workshop
Learn To Test Like A Grumpy Programmer - 3 hour workshopLearn To Test Like A Grumpy Programmer - 3 hour workshop
Learn To Test Like A Grumpy Programmer - 3 hour workshopchartjes
 

What's hot (20)

7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)7 Common Mistakes in Go (2015)
7 Common Mistakes in Go (2015)
 
Introduction to Go programming language
Introduction to Go programming languageIntroduction to Go programming language
Introduction to Go programming language
 
Introduction to Programming in Go
Introduction to Programming in GoIntroduction to Programming in Go
Introduction to Programming in Go
 
Learning Python from Data
Learning Python from DataLearning Python from Data
Learning Python from Data
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminary
 
An Overview Of Standard C++Tr1
An Overview Of Standard C++Tr1An Overview Of Standard C++Tr1
An Overview Of Standard C++Tr1
 
Beyond the Style Guides
Beyond the Style GuidesBeyond the Style Guides
Beyond the Style Guides
 
Dynamic Python
Dynamic PythonDynamic Python
Dynamic Python
 
Programming with Python - Basic
Programming with Python - BasicProgramming with Python - Basic
Programming with Python - Basic
 
Interfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIGInterfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIG
 
A deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio moduleA deep dive into PEP-3156 and the new asyncio module
A deep dive into PEP-3156 and the new asyncio module
 
C++11 talk
C++11 talkC++11 talk
C++11 talk
 
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
An Embedded Error Recovery and Debugging Mechanism for Scripting Language Ext...
 
Using SWIG to Control, Prototype, and Debug C Programs with Python
Using SWIG to Control, Prototype, and Debug C Programs with PythonUsing SWIG to Control, Prototype, and Debug C Programs with Python
Using SWIG to Control, Prototype, and Debug C Programs with Python
 
Hourglass Interfaces for C++ APIs - CppCon 2014
Hourglass Interfaces for C++ APIs - CppCon 2014Hourglass Interfaces for C++ APIs - CppCon 2014
Hourglass Interfaces for C++ APIs - CppCon 2014
 
The Benefits of Type Hints
The Benefits of Type HintsThe Benefits of Type Hints
The Benefits of Type Hints
 
PyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtimePyPy's approach to construct domain-specific language runtime
PyPy's approach to construct domain-specific language runtime
 
Дмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI векеДмитрий Нестерук, Паттерны проектирования в XXI веке
Дмитрий Нестерук, Паттерны проектирования в XXI веке
 
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017Briefly Rust - Daniele Esposti - Codemotion Rome 2017
Briefly Rust - Daniele Esposti - Codemotion Rome 2017
 
Learn To Test Like A Grumpy Programmer - 3 hour workshop
Learn To Test Like A Grumpy Programmer - 3 hour workshopLearn To Test Like A Grumpy Programmer - 3 hour workshop
Learn To Test Like A Grumpy Programmer - 3 hour workshop
 

Similar to Gcrc talk

Python and Pytorch tutorial and walkthrough
Python and Pytorch tutorial and walkthroughPython and Pytorch tutorial and walkthrough
Python and Pytorch tutorial and walkthroughgabriellekuruvilla
 
Extending Python - EuroPython 2014
Extending Python - EuroPython 2014Extending Python - EuroPython 2014
Extending Python - EuroPython 2014fcofdezc
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaCharles Nutter
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationGlobalLogic Ukraine
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Sebastian Witowski
 
What is Python?
What is Python?What is Python?
What is Python?PranavSB
 
Statically Compiling Ruby with LLVM
Statically Compiling Ruby with LLVMStatically Compiling Ruby with LLVM
Statically Compiling Ruby with LLVMLaurent Sansonetti
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGautam Rege
 
Machine Learning on Code - SF meetup
Machine Learning on Code - SF meetupMachine Learning on Code - SF meetup
Machine Learning on Code - SF meetupsource{d}
 
Python 3.6 Features 20161207
Python 3.6 Features 20161207Python 3.6 Features 20161207
Python 3.6 Features 20161207Jay Coskey
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtextmeysholdt
 
web programming UNIT VIII python by Bhavsingh Maloth
web programming UNIT VIII python by Bhavsingh Malothweb programming UNIT VIII python by Bhavsingh Maloth
web programming UNIT VIII python by Bhavsingh MalothBhavsingh Maloth
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20DefconRussia
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for DummiesElizabeth Smith
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityGeorgePeterBanyard
 
Monitoraggio del Traffico di Rete Usando Python ed ntop
Monitoraggio del Traffico di Rete Usando Python ed ntopMonitoraggio del Traffico di Rete Usando Python ed ntop
Monitoraggio del Traffico di Rete Usando Python ed ntopPyCon Italia
 

Similar to Gcrc talk (20)

Php extensions
Php extensionsPhp extensions
Php extensions
 
Python and Pytorch tutorial and walkthrough
Python and Pytorch tutorial and walkthroughPython and Pytorch tutorial and walkthrough
Python and Pytorch tutorial and walkthrough
 
Extending Python - EuroPython 2014
Extending Python - EuroPython 2014Extending Python - EuroPython 2014
Extending Python - EuroPython 2014
 
Fast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible JavaFast as C: How to Write Really Terrible Java
Fast as C: How to Write Really Terrible Java
 
Modern C++
Modern C++Modern C++
Modern C++
 
Boost.Python: C++ and Python Integration
Boost.Python: C++ and Python IntegrationBoost.Python: C++ and Python Integration
Boost.Python: C++ and Python Integration
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)
 
What is Python?
What is Python?What is Python?
What is Python?
 
Statically Compiling Ruby with LLVM
Statically Compiling Ruby with LLVMStatically Compiling Ruby with LLVM
Statically Compiling Ruby with LLVM
 
GoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPHGoFFIng around with Ruby #RubyConfPH
GoFFIng around with Ruby #RubyConfPH
 
Machine Learning on Code - SF meetup
Machine Learning on Code - SF meetupMachine Learning on Code - SF meetup
Machine Learning on Code - SF meetup
 
Python 3.6 Features 20161207
Python 3.6 Features 20161207Python 3.6 Features 20161207
Python 3.6 Features 20161207
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtext
 
web programming UNIT VIII python by Bhavsingh Maloth
web programming UNIT VIII python by Bhavsingh Malothweb programming UNIT VIII python by Bhavsingh Maloth
web programming UNIT VIII python by Bhavsingh Maloth
 
Zn task - defcon russia 20
Zn task  - defcon russia 20Zn task  - defcon russia 20
Zn task - defcon russia 20
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
Monitoraggio del Traffico di Rete Usando Python ed ntop
Monitoraggio del Traffico di Rete Usando Python ed ntopMonitoraggio del Traffico di Rete Usando Python ed ntop
Monitoraggio del Traffico di Rete Usando Python ed ntop
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
 

Gcrc talk

  • 1. Native Extensions Served 3 Ways Tejas Dinkar Nilenso Software
  • 2. about.me • Hi, I’m Tejas • Nilenso: Partner • twitter: tdinkar • github: gja
  • 3. about.talk • Expect to see lots of code • Will have about 5 minutes for questions • Please laugh at my jokes! • Will cover C Extensions, FFI and SWIG
  • 4. Native Extensions • Integrate with new libraries • Improve Performance of critical code • Write code that works across languages • Feel super 1337
  • 5. Let’s talk about Python • Pythonista’s in the house? • Yes, I’m trolling you! http://montgomeryq.blogspot.in/2011/05/random-illustration-tuesday-python-ruby.html
  • 6.
  • 7. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 8. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 9. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 10. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 11. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 12. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 13. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 14. #include "Python.h" #include "ruby.h" ! static PyObject *python_ruby_eval(PyObject *self, PyObject *string) { VALUE val = rb_eval_string(PyString_AsString(string)); switch(TYPE(val)) { case T_FIXNUM: return PyInt_FromLong(FIX2INT(val)); case T_STRING: return PyString_FromString(StringValuePtr(val)); default: return Py_None; // Can handle these cases later } } ! static PyMethodDef module_functions[] = { { "eval", python_ruby_eval, METH_O, "Evaluate Ruby Code" }, { NULL } }; ! void initruby(void) { ruby_init(); Py_InitModule3("ruby", module_functions, "A ruby module for python."); }
  • 15. Require Files? static PyObject *python_ruby_require(PyObject *self, PyObject *file) { rb_require(PyString_AsString(file)); return Py_True; }
  • 18. Memory Management • Data_Wrap_Struct(klass, mark_cb, free_cb, *data) • Data_Get_Struct( VALUE, data_type, data* )
  • 21. string.c void Init_String(void) {! rb_cString = rb_define_class("String", rb_cObject);! // ...! rb_define_method(rb_cString, "eql?", rb_str_eql, 1);! rb_define_method(rb_cString, "==", rb_str_equal, 1);! // ...! rb_define_method(rb_cString, "insert", rb_str_insert, 2);! rb_define_method(rb_cString, "length", rb_str_length, 0);! // ...! }! ! static VALUE rb_str_eql(VALUE self, VALUE str2)! {! if (self == str2) return Qtrue;! if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;! return str_eql(self, str2);! }!
  • 22. string.c void Init_String(void) {! rb_cString = rb_define_class("String", rb_cObject);! // ...! rb_define_method(rb_cString, "eql?", rb_str_eql, 1);! rb_define_method(rb_cString, "==", rb_str_equal, 1);! // ...! rb_define_method(rb_cString, "insert", rb_str_insert, 2);! rb_define_method(rb_cString, "length", rb_str_length, 0);! // ...! }! ! static VALUE rb_str_eql(VALUE str2, VALUE str2)! {! if (self == str2) return Qtrue;! if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;! return str_eql(self, str2);! }!
  • 23. string.c void Init_String(void) {! rb_cString = rb_define_class("String", rb_cObject);! // ...! rb_define_method(rb_cString, "eql?", rb_str_eql, 1);! rb_define_method(rb_cString, "==", rb_str_equal, 1);! // ...! rb_define_method(rb_cString, "insert", rb_str_insert, 2);! rb_define_method(rb_cString, "length", rb_str_length, 0);! // ...! }! ! static VALUE rb_str_eql(VALUE str2, VALUE str2)! {! if (self == str2) return Qtrue;! if (!RB_TYPE_P(str2, T_STRING)) return Qfalse;! return str_eql(self, str2);! }!
  • 24. C Extensions Native Code Ruby Aware! Native Code Ruby Code
  • 25. Foreign Function Interface Native Code Native Aware! Ruby Code Ruby Code
  • 26. Foreign Function Interface • A Ruby DSL • Works across all Ruby Implementations • Converts to and from C primitives for you
  • 27. example require 'ffi'! ! module MyLib! extend FFI::Library! ffi_lib 'c'! attach_function :puts, [:string], :int! end! ! MyLib.puts 'Hello, World using libc!'
  • 28. another example require 'ffi'! ! module MyMathLib! extend FFI::Library! ffi_lib 'm'! attach_function :pow, [:double, :double],! :double! end! ! MyMathLib.pow(4, 5) # => 1024.0
  • 29. Lots of built in types Numbers!! ! ! ! ! Character!! ! ! ! ! Other! :int! ! ! ! ! ! ! :char!! ! ! ! ! ! ! :pointer! :short! ! ! ! ! ! :string! :long! :double! :float!
  • 30. Foreign Function Interface • Probably your best solution • It’s really easy • Do your modelling in Ruby • Still have to worry about GC • Sadly, no C++ without wrapping
  • 31. Memory in FFI def run_query_which_will_crash! db_connection = MyFFIModule.database_connection("localhost")! MyFFIModule.database_query(db_connection, "select * from users")! end!
  • 32. Memory in FFI This will get GCed def run_query_which_will_crash! db_connection = MyFFIModule.database_connection("localhost")! MyFFIModule.database_query(db_connection, "select * from users")! end!
  • 33. SWIG • Simplified Wrapper and Interface Generator • Annotate your C/C++ header files • It generates native extensions for languages • About 20 languages currently supported
  • 35. The Magic • Takes an interface file • Auto generates code to make it work • For ruby, it’s a `regular’ C extension • For python, it’s a a .c and .py file • For Java it’s a JNI interface • Still need to do your own GC
  • 36. The Rectangle class Rectangle! {! int length;! int breadth;! ! public:! Rectangle(int length, int breadth);! int area();! };
  • 37. The Rectangle #ifdef SWIG %module shape %{ SWIG Stuff Here class Rectangle! {! int length;! int breadth;! ! public:! Rectangle(int length, int breadth);! int area();! }; %}
  • 38. require 'shapes'! ! rectangle = shapes.Rectangle.new(10, 12)! rectangle.area == 120!
  • 39. Other Options • DL (Dynamic Load) • Fiddle(r)
  • 40. TL;DR • Native Extensions are fun and easy to build • The three big tools • You want to pick FFI if you don’t maintain the lib • SWIG may be better if you are a maintainer
  • 41. Thank You super integration wow so extension so native ruby = win wow such easy Many Questions? no python such performance