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.");
}
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
37. The Rectangle
#ifdef SWIG
%module shape
%{
SWIG Stuff Here
class Rectangle!
{!
int length;!
int breadth;!
!
public:!
Rectangle(int length, int breadth);!
int area();!
};
%}
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