SlideShare a Scribd company logo
1 of 45
Download to read offline
Build the C link
          Nikhil Marathe
Introduction

 • V8 is a powerful, fast JavaScript engine
 • It is self contained and easy to embed
     JS is the new Lua?
 • node.js is a thin wrapper around V8 and evented I/O (libuv)
Follow along
Slides and code
   git clone git://github.com/nikhilm/jsfoo-pune-2012.git
We want to


Use C/C++ libraries in node.js
Exchange data between C++ ⇔ JS
Do asynchronous I/O
Getting started

#include <v8.h>
#include <node.h>

using namespace v8;

extern "C" {
    static void Init(Handle<Object> target) {
    }
    NODE_MODULE(firststep, Init)
}
Build

# firststep/wscript
import Options

def set_options(opt):
    opt.tool_options("compiler_cxx")

def configure(conf):
    conf.check_tool("compiler_cxx")
    conf.check_tool("node_addon")

def build(bld):
    obj = bld.new_task_gen("cxx", "shlib", "node_addon")
    obj.target = "firststep"
    obj.source = "firststep.cc"
Run

$ node-waf configure build
...
'build' finished successfully (0.327s)

$ node

> require('./build/Release/firststep')
{}
Architecture




1          you will need http://bespin.cz/~ondras/html/index.html
Handles

 • Think of them as smart pointers, GCed by V8
 • Also encode scope (Use HandleScope to manage handles)
 • Local - GCed as they go out of scope:

   Local<String> name; // also Handle<...>

 • Persistent - Must be manually disposed:

   Persistent<String> globalVariable;
Injecting primitives
#include <math.h>
#include <v8.h>
#include <node.h>
#include <node_version.h>
using namespace v8;

extern "C" {
    static void Init(Handle<Object> target) {
        target->Set(String::NewSymbol("pi"),
                    Number::New(M_PI));

        NODE_DEFINE_CONSTANT(target, NODE_MINOR_VERSION);

        target->Set(String::New("name"), String::New("Nikhil"));
    }
    NODE_MODULE(primitives, Init)
}
Simple functions




 exports.square = function(n) {
     return n * n;
 }

We want to do this in C++
Simple functions
Registering with V8:

 Handle<Value> Square(const Arguments &args)

 static void Init(Handle<Object> target) {
         HandleScope scope;

          Handle<FunctionTemplate> squareTpl =
              FunctionTemplate::New(Square);

          target->Set(String::New("square"),
                      squareTpl->GetFunction());
     }
Simple functions
Implementation:

 Handle<Value> Square(const Arguments &args) {
     HandleScope scope;

     int a = args[0]->Int32Value();
     int sq = a * a;

     return scope.Close(Integer::New(sq));
 }

explain scope.Close
Templates
FunctionTemplate                        ???

FunctionTemplate::GetFunction           square [Function]

FunctionTemplate::InstanceTemplate()    What `this` would be in 'new square()'

FunctionTemplate::PrototypeTemplate()   square.prototype
Simple objects



 exports.Inventory = function() {
     this.items = 257;
 }

 // later
 var iv = new Inventory();
 console.log(iv.items);

This is the classic object oriented JS style
Simple objects
static void Init(Handle<Object> target) {
        HandleScope scope;

        Handle<FunctionTemplate> inventoryTpl =
            FunctionTemplate::New(Inventory);

        Handle<ObjectTemplate> instance =
            inventoryTpl->InstanceTemplate();

        instance->Set(String::New("items"), Integer::New(257));

        target->Set(String::NewSymbol("Inventory"),
                    inventoryTpl->GetFunction());
    }


Handle<Value> Inventory(const Arguments &args) {
    return args.This();
}
Methods

Inventory.prototype.addStock = function(newStock) {
    this.items += newStock;
}

Inventory.prototype.ship = function(orders) {
    if (this.items < orders)
        throw Exception("Not enough items");

    this.items -= orders
}
Methods
Registering prototype methods

 // operating on inventoryTpl->PrototypeTemplate()
         NODE_SET_PROTOTYPE_METHOD(inventoryTpl,
                                   "addStock",
                                   AddStock);
         NODE_SET_PROTOTYPE_METHOD(inventoryTpl,
                                   "ship",
                                   Ship);

         target->Set(String::NewSymbol("Inventory"),
                     inventoryTpl->GetFunction());
Methods
Accessing object properties
Handle<Value> AddStock(const Arguments &args) {
    HandleScope scope;

    Handle<Object> This = args.This();

    int items = This->Get(String::New("items"))->Uint32Value();

    items += args[0]->Uint32Value();

    This->Set(String::New("items"), Integer::New(items));

    return Undefined();
}
Methods
Throwing an exception
Handle<Value> Ship(const Arguments &args) {
    HandleScope scope;

    Handle<Object> This = args.This();
    int items = This->Get(String::New("items"))->Uint32Value();

    int orders = args[0]->Uint32Value();

    if (items < orders)
        return ThrowException(String::New("Not enough items"));

    This->Set(String::New("items"), Integer::New(items - orders));

    return Undefined();
}
ObjectWrap

 • Associate native C++ objects with JS objects
 • Node specific class which manages garbage collection
 • Stored internally in fields
ObjectWrap

// native C++ class
namespace Library {
class Inventory {
    Inventory();
    void addStock(int);
    int ship(int);
    int getItems();

     int items; // private
};
}
ObjectWrap
Setting internal field count

 Handle<ObjectTemplate> instance =
             inventoryTpl->InstanceTemplate();

          instance->SetInternalFieldCount(1);
ObjectWrap
Wrapping

namespace binding {
class Inventory : public ObjectWrap {
public:
    static Handle<Value> New(const Arguments &args) {
        Inventory *wrapper = new Inventory();
        wrapper->Wrap(args.Holder());
        return args.Holder();
    }
ObjectWrap
Unwrapping
static Handle<Value> Ship(const Arguments &args) {
        // extract
        Inventory *wrapper = Unwrap<Inventory>(args.Holder());

        int orders = args[0]->Uint32Value();
        int result = wrapper->inv->ship(orders);

        if (result == -1)
            return ThrowException(String::New("Not enough items"));

        return Undefined();
    }
Going Async

 • The easiest way is to use uv_queue_work()
 • Every async call requires a set of 3 functions

       1. Set up and invoke uv_queue_work()
      2. Do blocking task (run in separate thread)
       3. Clean up (run in main thread)
 • Use a 'baton' to pass around data

       • uv_request_t is used by libuv
         • But it’s data field is important to store the baton
           itself
 • Slightly cumbersome :(
Going Async
var inv = new (require('./build/Release/async')).Inventory()

inv.reshelve(function() {
    console.log("Reshelving done");
})
console.log("After reshelve in source");
for (var i = 1; i < 5; i++)
    setTimeout(function() {
        console.log("Tick");
    }, i*1000);
Going Async
The native blocking code (method of class Library::Inventory)

 void reshelve() {
         sleep(5);
     }
Going Async
The baton
struct ReshelveBaton {
    uv_work_t request;
    Persistent<Function> callback;
    Inventory *wrapper;
    // any other data that has to be sent to the callback
    // or for async processing.
}
Going Async
JS callback
static Handle<Value> Reshelve(const Arguments &args) {
        Inventory *wrapper = Unwrap<Inventory>(args.Holder());

        Handle<Function> cb = Handle<Function>::Cast(args[0]);

        ReshelveBaton *baton = new ReshelveBaton();
        baton->request.data = baton;
        baton->callback = Persistent<Function>::New(cb);
        baton->wrapper = wrapper;

        uv_queue_work(Loop(), &baton->request,
                      ReshelveAsync, ReshelveAsyncAfter);

        return Undefined();
    }
Going Async
Thread pool function

 static void ReshelveAsync(uv_work_t *req) {
         // This runs in a separate thread
         // NO V8 interaction should be done
         ReshelveBaton *baton =
             static_cast<ReshelveBaton*>(req->data);
         // if you want to modify baton values
         // do synchronous work here
         baton->wrapper->inv->reshelve();
     }
Going Async
Clean up
static void ReshelveAsyncAfter(uv_work_t *req) {
        ReshelveBaton *baton =
            static_cast<ReshelveBaton*>(req->data);

           Handle<Value> argv[] = { Null() }; // no error
           baton->callback->Call(Context::GetCurrent()->Global(),
                                 1, argv);

           baton->callback.Dispose();
           delete baton;
    }
Going Async
Output

After reshelve in source
Tick
Tick
Tick
Tick
Reshelving done
Linking your library
Linking external libs in Waf:
def configure(conf):
  # ...
  # uses pkg-config
  conf.check_cfg(package='<pkg-config name>', args='--cflags --libs',
  uselib_store='ALIAS')

def build(bld):
  # ...
  obj.uselib = 'ALIAS'
Holder vs This

 • args.This() is always the this object passed in to the function
 • args.Holder() runs up the prototype chain to the ‘right’
   object
 • Signatures decide the ‘right’ object, automatically handled
   by NODE_PROTOTYPE_SET_METHOD
 • Always use Holder() to be on the safe side
Things I haven’t covered

 • Accessors

        • Per property accessors
        • Indexed accessors ( object[5] )
        • Named property accessors ( object.property )
 • Function Signatures and HasInstance for type safety
 • Emitting events using new JS only EventEmitter
 • Details of libuv
 • Using V8 on its own
You might want to look at

 • https://github.com/weaver/uuidjs
 • https://github.com/nikhilm/node-taglib
 • https://github.com/pietern/hiredis-node
End notes
Contact:
  • @nikhilcutshort
  • nsm.nikhil@gmail.com



Cover image by Munjal Savla (by-nc-sa)
Extra material below
Calling JS functions

var calljs = require("./build/Release/calljs")

var f = function() {
    console.log("This", this);
    console.log(arguments);
}

calljs.apply(f, { cool: "dude" }, "one", 2, 3.14);
Calling JS functions
Handle<Value> Apply(const Arguments &args) {
    HandleScope scope;

    Handle<Function> func = Handle<Function>::Cast(args[0]);
    Handle<Object> receiver = args[1]->ToObject();

    Handle<Value> *argv = new Handle<Value>[args.Length() - 2];
    for (int i = 2; i < args.Length(); i++)
        argv[i-2] = args[i];

    func->Call(receiver, args.Length()-2, argv);

    delete argv;
    return Undefined();
}
Strings to-and-fro
v8::String -> C string

 Handle<Value> Print(const Arguments &args) {
     HandleScope scope;

     for (int i = 0; i < args.Length(); i++) {
         if (!args[i]->IsString())
             continue;

          // also String::AsciiValue
          String::Utf8Value val(args[i]);
          printf("%s ", *val); // <<<<<<
     }
     return Undefined();
 }
Strings to-and-fro
C string -> v8::String
Handle<Value> Read(const Arguments &args) {
    HandleScope scope;

     char str[1024];
     fgets(str, 1023, stdin);

     Local<String> v8String = String::New(str, strlen(str));
     return scope.Close(v8String);
}

More Related Content

What's hot

All you need to know about the JavaScript event loop
All you need to know about the JavaScript event loopAll you need to know about the JavaScript event loop
All you need to know about the JavaScript event loopSaša Tatar
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopPeter Friese
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXLRob Gietema
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux IntroductionNikolaus Graf
 
Authenticating Angular Apps with JWT
Authenticating Angular Apps with JWTAuthenticating Angular Apps with JWT
Authenticating Angular Apps with JWTJennifer Estrada
 
React JS - A quick introduction tutorial
React JS - A quick introduction tutorialReact JS - A quick introduction tutorial
React JS - A quick introduction tutorialMohammed Fazuluddin
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to HooksSoluto
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js ExpressEyal Vardi
 
All about Context API
All about Context APIAll about Context API
All about Context APISouvik Basu
 
React Context API
React Context APIReact Context API
React Context APINodeXperts
 
JavaScript - Chapter 1 - Problem Solving
 JavaScript - Chapter 1 - Problem Solving JavaScript - Chapter 1 - Problem Solving
JavaScript - Chapter 1 - Problem SolvingWebStackAcademy
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentationBojan Golubović
 
Express JS Middleware Tutorial
Express JS Middleware TutorialExpress JS Middleware Tutorial
Express JS Middleware TutorialSimplilearn
 
How to get along with HATEOAS without letting the bad guys steal your lunch?
How to get along with HATEOAS without letting the bad guys steal your lunch?How to get along with HATEOAS without letting the bad guys steal your lunch?
How to get along with HATEOAS without letting the bad guys steal your lunch?Graham Charters
 

What's hot (20)

React and redux
React and reduxReact and redux
React and redux
 
EVOLVE'13 | Keynote | Roy Fielding
EVOLVE'13 | Keynote | Roy FieldingEVOLVE'13 | Keynote | Roy Fielding
EVOLVE'13 | Keynote | Roy Fielding
 
All you need to know about the JavaScript event loop
All you need to know about the JavaScript event loopAll you need to know about the JavaScript event loop
All you need to know about the JavaScript event loop
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXL
 
Express js
Express jsExpress js
Express js
 
React + Redux Introduction
React + Redux IntroductionReact + Redux Introduction
React + Redux Introduction
 
Authenticating Angular Apps with JWT
Authenticating Angular Apps with JWTAuthenticating Angular Apps with JWT
Authenticating Angular Apps with JWT
 
React JS - A quick introduction tutorial
React JS - A quick introduction tutorialReact JS - A quick introduction tutorial
React JS - A quick introduction tutorial
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
 
React new features and intro to Hooks
React new features and intro to HooksReact new features and intro to Hooks
React new features and intro to Hooks
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
MEAN Stack
MEAN Stack MEAN Stack
MEAN Stack
 
All about Context API
All about Context APIAll about Context API
All about Context API
 
JS Event Loop
JS Event LoopJS Event Loop
JS Event Loop
 
React Context API
React Context APIReact Context API
React Context API
 
JavaScript - Chapter 1 - Problem Solving
 JavaScript - Chapter 1 - Problem Solving JavaScript - Chapter 1 - Problem Solving
JavaScript - Chapter 1 - Problem Solving
 
React workshop presentation
React workshop presentationReact workshop presentation
React workshop presentation
 
Express JS Middleware Tutorial
Express JS Middleware TutorialExpress JS Middleware Tutorial
Express JS Middleware Tutorial
 
How to get along with HATEOAS without letting the bad guys steal your lunch?
How to get along with HATEOAS without letting the bad guys steal your lunch?How to get along with HATEOAS without letting the bad guys steal your lunch?
How to get along with HATEOAS without letting the bad guys steal your lunch?
 

Viewers also liked

Node.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsNode.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsChris Barber
 
node-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.jsnode-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.jsMariano Iglesias
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboyKenneth Geisshirt
 
Mastering the IoT With JavaScript and C++ - Günter Obiltschnig
Mastering the IoT With JavaScript and C++ - Günter ObiltschnigMastering the IoT With JavaScript and C++ - Günter Obiltschnig
Mastering the IoT With JavaScript and C++ - Günter ObiltschnigWithTheBest
 
Writing Node.js Bindings - General Principles - Gabriel Schulhof
Writing Node.js Bindings - General Principles - Gabriel SchulhofWriting Node.js Bindings - General Principles - Gabriel Schulhof
Writing Node.js Bindings - General Principles - Gabriel SchulhofWithTheBest
 
Informix - The Ideal Database for IoT
Informix - The Ideal Database for IoTInformix - The Ideal Database for IoT
Informix - The Ideal Database for IoTPradeep Natarajan
 
Preparing for a technical interview
Preparing for a technical interviewPreparing for a technical interview
Preparing for a technical interviewpocketgems
 
How to use Hadoop for operational and transactional purposes by RODRIGO MERI...
 How to use Hadoop for operational and transactional purposes by RODRIGO MERI... How to use Hadoop for operational and transactional purposes by RODRIGO MERI...
How to use Hadoop for operational and transactional purposes by RODRIGO MERI...Big Data Spain
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907NodejsFoundation
 
Functional Programming with Streams in node.js
Functional Programming with Streams in node.jsFunctional Programming with Streams in node.js
Functional Programming with Streams in node.jsAdam Crabtree
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at NetflixBrendan Gregg
 

Viewers also liked (14)

Node.js/io.js Native C++ Addons
Node.js/io.js Native C++ AddonsNode.js/io.js Native C++ Addons
Node.js/io.js Native C++ Addons
 
Node.js extensions in C++
Node.js extensions in C++Node.js extensions in C++
Node.js extensions in C++
 
Extending Node.js using C++
Extending Node.js using C++Extending Node.js using C++
Extending Node.js using C++
 
node-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.jsnode-db: La excusa perfecta para hablar de C++ y Node.js
node-db: La excusa perfecta para hablar de C++ y Node.js
 
Unleash your inner console cowboy
Unleash your inner console cowboyUnleash your inner console cowboy
Unleash your inner console cowboy
 
Mastering the IoT With JavaScript and C++ - Günter Obiltschnig
Mastering the IoT With JavaScript and C++ - Günter ObiltschnigMastering the IoT With JavaScript and C++ - Günter Obiltschnig
Mastering the IoT With JavaScript and C++ - Günter Obiltschnig
 
Slidecast power point
Slidecast power pointSlidecast power point
Slidecast power point
 
Writing Node.js Bindings - General Principles - Gabriel Schulhof
Writing Node.js Bindings - General Principles - Gabriel SchulhofWriting Node.js Bindings - General Principles - Gabriel Schulhof
Writing Node.js Bindings - General Principles - Gabriel Schulhof
 
Informix - The Ideal Database for IoT
Informix - The Ideal Database for IoTInformix - The Ideal Database for IoT
Informix - The Ideal Database for IoT
 
Preparing for a technical interview
Preparing for a technical interviewPreparing for a technical interview
Preparing for a technical interview
 
How to use Hadoop for operational and transactional purposes by RODRIGO MERI...
 How to use Hadoop for operational and transactional purposes by RODRIGO MERI... How to use Hadoop for operational and transactional purposes by RODRIGO MERI...
How to use Hadoop for operational and transactional purposes by RODRIGO MERI...
 
Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907Node Foundation Membership Overview 20160907
Node Foundation Membership Overview 20160907
 
Functional Programming with Streams in node.js
Functional Programming with Streams in node.jsFunctional Programming with Streams in node.js
Functional Programming with Streams in node.js
 
Linux Profiling at Netflix
Linux Profiling at NetflixLinux Profiling at Netflix
Linux Profiling at Netflix
 

Similar to Writing native bindings to node.js in C++

In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxbradburgess22840
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript EverywherePascal Rettig
 
JVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksJVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksDoug Hawkins
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42Yevhen Bobrov
 
삼성 바다 앱개발 실패 노하우 2부
삼성 바다 앱개발 실패 노하우 2부삼성 바다 앱개발 실패 노하우 2부
삼성 바다 앱개발 실패 노하우 2부mosaicnet
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js ModuleFred Chien
 
The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210Mahmoud Samir Fayed
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgetsscottw
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3Simon Su
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone DevelopmentGiordano Scalzo
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)Piyush Katariya
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptSaadAsim11
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 SpringKiyotaka Oku
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJavaJobaer Chowdhury
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)BoneyGawande
 

Similar to Writing native bindings to node.js in C++ (20)

In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docxIn Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
In Class AssignmetzCST280W13a-1.pdfCST 280 In-Class Pract.docx
 
Javascript Everywhere
Javascript EverywhereJavascript Everywhere
Javascript Everywhere
 
JVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's TricksJVM Mechanics: Understanding the JIT's Tricks
JVM Mechanics: Understanding the JIT's Tricks
 
The uniform interface is 42
The uniform interface is 42The uniform interface is 42
The uniform interface is 42
 
Day 1
Day 1Day 1
Day 1
 
V8
V8V8
V8
 
삼성 바다 앱개발 실패 노하우 2부
삼성 바다 앱개발 실패 노하우 2부삼성 바다 앱개발 실패 노하우 2부
삼성 바다 앱개발 실패 노하우 2부
 
How to Write Node.js Module
How to Write Node.js ModuleHow to Write Node.js Module
How to Write Node.js Module
 
The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210The Ring programming language version 1.9 book - Part 90 of 210
The Ring programming language version 1.9 book - Part 90 of 210
 
Build Widgets
Build WidgetsBuild Widgets
Build Widgets
 
Google App Engine Developer - Day3
Google App Engine Developer - Day3Google App Engine Developer - Day3
Google App Engine Developer - Day3
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
 
JavaScript (without DOM)
JavaScript (without DOM)JavaScript (without DOM)
JavaScript (without DOM)
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
OBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .pptOBJECTS IN Object Oriented Programming .ppt
OBJECTS IN Object Oriented Programming .ppt
 
JJUG CCC 2011 Spring
JJUG CCC 2011 SpringJJUG CCC 2011 Spring
JJUG CCC 2011 Spring
 
Reactive programming with RxJava
Reactive programming with RxJavaReactive programming with RxJava
Reactive programming with RxJava
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
 
I os 04
I os 04I os 04
I os 04
 

Recently uploaded

Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 

Recently uploaded (20)

Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 

Writing native bindings to node.js in C++

  • 1. Build the C link Nikhil Marathe
  • 2. Introduction • V8 is a powerful, fast JavaScript engine • It is self contained and easy to embed JS is the new Lua? • node.js is a thin wrapper around V8 and evented I/O (libuv)
  • 3. Follow along Slides and code git clone git://github.com/nikhilm/jsfoo-pune-2012.git
  • 4. We want to Use C/C++ libraries in node.js Exchange data between C++ ⇔ JS Do asynchronous I/O
  • 5. Getting started #include <v8.h> #include <node.h> using namespace v8; extern "C" { static void Init(Handle<Object> target) { } NODE_MODULE(firststep, Init) }
  • 6. Build # firststep/wscript import Options def set_options(opt): opt.tool_options("compiler_cxx") def configure(conf): conf.check_tool("compiler_cxx") conf.check_tool("node_addon") def build(bld): obj = bld.new_task_gen("cxx", "shlib", "node_addon") obj.target = "firststep" obj.source = "firststep.cc"
  • 7. Run $ node-waf configure build ... 'build' finished successfully (0.327s) $ node > require('./build/Release/firststep') {}
  • 8. Architecture 1 you will need http://bespin.cz/~ondras/html/index.html
  • 9.
  • 10. Handles • Think of them as smart pointers, GCed by V8 • Also encode scope (Use HandleScope to manage handles) • Local - GCed as they go out of scope: Local<String> name; // also Handle<...> • Persistent - Must be manually disposed: Persistent<String> globalVariable;
  • 11. Injecting primitives #include <math.h> #include <v8.h> #include <node.h> #include <node_version.h> using namespace v8; extern "C" { static void Init(Handle<Object> target) { target->Set(String::NewSymbol("pi"), Number::New(M_PI)); NODE_DEFINE_CONSTANT(target, NODE_MINOR_VERSION); target->Set(String::New("name"), String::New("Nikhil")); } NODE_MODULE(primitives, Init) }
  • 12. Simple functions exports.square = function(n) { return n * n; } We want to do this in C++
  • 13. Simple functions Registering with V8: Handle<Value> Square(const Arguments &args) static void Init(Handle<Object> target) { HandleScope scope; Handle<FunctionTemplate> squareTpl = FunctionTemplate::New(Square); target->Set(String::New("square"), squareTpl->GetFunction()); }
  • 14. Simple functions Implementation: Handle<Value> Square(const Arguments &args) { HandleScope scope; int a = args[0]->Int32Value(); int sq = a * a; return scope.Close(Integer::New(sq)); } explain scope.Close
  • 15. Templates FunctionTemplate ??? FunctionTemplate::GetFunction square [Function] FunctionTemplate::InstanceTemplate() What `this` would be in 'new square()' FunctionTemplate::PrototypeTemplate() square.prototype
  • 16. Simple objects exports.Inventory = function() { this.items = 257; } // later var iv = new Inventory(); console.log(iv.items); This is the classic object oriented JS style
  • 17. Simple objects static void Init(Handle<Object> target) { HandleScope scope; Handle<FunctionTemplate> inventoryTpl = FunctionTemplate::New(Inventory); Handle<ObjectTemplate> instance = inventoryTpl->InstanceTemplate(); instance->Set(String::New("items"), Integer::New(257)); target->Set(String::NewSymbol("Inventory"), inventoryTpl->GetFunction()); } Handle<Value> Inventory(const Arguments &args) { return args.This();
  • 18. }
  • 19. Methods Inventory.prototype.addStock = function(newStock) { this.items += newStock; } Inventory.prototype.ship = function(orders) { if (this.items < orders) throw Exception("Not enough items"); this.items -= orders }
  • 20. Methods Registering prototype methods // operating on inventoryTpl->PrototypeTemplate() NODE_SET_PROTOTYPE_METHOD(inventoryTpl, "addStock", AddStock); NODE_SET_PROTOTYPE_METHOD(inventoryTpl, "ship", Ship); target->Set(String::NewSymbol("Inventory"), inventoryTpl->GetFunction());
  • 21. Methods Accessing object properties Handle<Value> AddStock(const Arguments &args) { HandleScope scope; Handle<Object> This = args.This(); int items = This->Get(String::New("items"))->Uint32Value(); items += args[0]->Uint32Value(); This->Set(String::New("items"), Integer::New(items)); return Undefined(); }
  • 22. Methods Throwing an exception Handle<Value> Ship(const Arguments &args) { HandleScope scope; Handle<Object> This = args.This(); int items = This->Get(String::New("items"))->Uint32Value(); int orders = args[0]->Uint32Value(); if (items < orders) return ThrowException(String::New("Not enough items")); This->Set(String::New("items"), Integer::New(items - orders)); return Undefined(); }
  • 23. ObjectWrap • Associate native C++ objects with JS objects • Node specific class which manages garbage collection • Stored internally in fields
  • 24. ObjectWrap // native C++ class namespace Library { class Inventory { Inventory(); void addStock(int); int ship(int); int getItems(); int items; // private }; }
  • 25. ObjectWrap Setting internal field count Handle<ObjectTemplate> instance = inventoryTpl->InstanceTemplate(); instance->SetInternalFieldCount(1);
  • 26. ObjectWrap Wrapping namespace binding { class Inventory : public ObjectWrap { public: static Handle<Value> New(const Arguments &args) { Inventory *wrapper = new Inventory(); wrapper->Wrap(args.Holder()); return args.Holder(); }
  • 27. ObjectWrap Unwrapping static Handle<Value> Ship(const Arguments &args) { // extract Inventory *wrapper = Unwrap<Inventory>(args.Holder()); int orders = args[0]->Uint32Value(); int result = wrapper->inv->ship(orders); if (result == -1) return ThrowException(String::New("Not enough items")); return Undefined(); }
  • 28. Going Async • The easiest way is to use uv_queue_work() • Every async call requires a set of 3 functions 1. Set up and invoke uv_queue_work() 2. Do blocking task (run in separate thread) 3. Clean up (run in main thread) • Use a 'baton' to pass around data • uv_request_t is used by libuv • But it’s data field is important to store the baton itself • Slightly cumbersome :(
  • 29. Going Async var inv = new (require('./build/Release/async')).Inventory() inv.reshelve(function() { console.log("Reshelving done"); }) console.log("After reshelve in source"); for (var i = 1; i < 5; i++) setTimeout(function() { console.log("Tick"); }, i*1000);
  • 30. Going Async The native blocking code (method of class Library::Inventory) void reshelve() { sleep(5); }
  • 31. Going Async The baton struct ReshelveBaton { uv_work_t request; Persistent<Function> callback; Inventory *wrapper; // any other data that has to be sent to the callback // or for async processing. }
  • 32. Going Async JS callback static Handle<Value> Reshelve(const Arguments &args) { Inventory *wrapper = Unwrap<Inventory>(args.Holder()); Handle<Function> cb = Handle<Function>::Cast(args[0]); ReshelveBaton *baton = new ReshelveBaton(); baton->request.data = baton; baton->callback = Persistent<Function>::New(cb); baton->wrapper = wrapper; uv_queue_work(Loop(), &baton->request, ReshelveAsync, ReshelveAsyncAfter); return Undefined(); }
  • 33. Going Async Thread pool function static void ReshelveAsync(uv_work_t *req) { // This runs in a separate thread // NO V8 interaction should be done ReshelveBaton *baton = static_cast<ReshelveBaton*>(req->data); // if you want to modify baton values // do synchronous work here baton->wrapper->inv->reshelve(); }
  • 34. Going Async Clean up static void ReshelveAsyncAfter(uv_work_t *req) { ReshelveBaton *baton = static_cast<ReshelveBaton*>(req->data); Handle<Value> argv[] = { Null() }; // no error baton->callback->Call(Context::GetCurrent()->Global(), 1, argv); baton->callback.Dispose(); delete baton; }
  • 35. Going Async Output After reshelve in source Tick Tick Tick Tick Reshelving done
  • 36. Linking your library Linking external libs in Waf: def configure(conf): # ... # uses pkg-config conf.check_cfg(package='<pkg-config name>', args='--cflags --libs', uselib_store='ALIAS') def build(bld): # ... obj.uselib = 'ALIAS'
  • 37. Holder vs This • args.This() is always the this object passed in to the function • args.Holder() runs up the prototype chain to the ‘right’ object • Signatures decide the ‘right’ object, automatically handled by NODE_PROTOTYPE_SET_METHOD • Always use Holder() to be on the safe side
  • 38. Things I haven’t covered • Accessors • Per property accessors • Indexed accessors ( object[5] ) • Named property accessors ( object.property ) • Function Signatures and HasInstance for type safety • Emitting events using new JS only EventEmitter • Details of libuv • Using V8 on its own
  • 39. You might want to look at • https://github.com/weaver/uuidjs • https://github.com/nikhilm/node-taglib • https://github.com/pietern/hiredis-node
  • 40. End notes Contact: • @nikhilcutshort • nsm.nikhil@gmail.com Cover image by Munjal Savla (by-nc-sa)
  • 42. Calling JS functions var calljs = require("./build/Release/calljs") var f = function() { console.log("This", this); console.log(arguments); } calljs.apply(f, { cool: "dude" }, "one", 2, 3.14);
  • 43. Calling JS functions Handle<Value> Apply(const Arguments &args) { HandleScope scope; Handle<Function> func = Handle<Function>::Cast(args[0]); Handle<Object> receiver = args[1]->ToObject(); Handle<Value> *argv = new Handle<Value>[args.Length() - 2]; for (int i = 2; i < args.Length(); i++) argv[i-2] = args[i]; func->Call(receiver, args.Length()-2, argv); delete argv; return Undefined(); }
  • 44. Strings to-and-fro v8::String -> C string Handle<Value> Print(const Arguments &args) { HandleScope scope; for (int i = 0; i < args.Length(); i++) { if (!args[i]->IsString()) continue; // also String::AsciiValue String::Utf8Value val(args[i]); printf("%s ", *val); // <<<<<< } return Undefined(); }
  • 45. Strings to-and-fro C string -> v8::String Handle<Value> Read(const Arguments &args) { HandleScope scope; char str[1024]; fgets(str, 1023, stdin); Local<String> v8String = String::New(str, strlen(str)); return scope.Close(v8String); }