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

Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson AEM HUB
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with SpringJoshua Long
 
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...Edureka!
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework Serhat Can
 
Summer training presentation on "CORE JAVA".
Summer training presentation on "CORE JAVA".Summer training presentation on "CORE JAVA".
Summer training presentation on "CORE JAVA".SudhanshuVijay3
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API07.pallav
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot ApplicationsVMware Tanzu
 
A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin XPeppers
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVCIndicThreads
 
Spring andspringboot training
Spring andspringboot trainingSpring andspringboot training
Spring andspringboot trainingMallikarjuna G D
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework IntroductionAnuj Singh Rajput
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring bootAntoine Rey
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming LanguageGiuseppe Arici
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no KubernetesKelvin Silva
 

What's hot (20)

Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Spring User Guide
Spring User GuideSpring User Guide
Spring User Guide
 
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...
What Is Spring Framework In Java | Spring Framework Tutorial For Beginners Wi...
 
Introduction to Spring Framework
Introduction to Spring FrameworkIntroduction to Spring Framework
Introduction to Spring Framework
 
Summer training presentation on "CORE JAVA".
Summer training presentation on "CORE JAVA".Summer training presentation on "CORE JAVA".
Summer training presentation on "CORE JAVA".
 
Spring Boot and REST API
Spring Boot and REST APISpring Boot and REST API
Spring Boot and REST API
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot Applications
 
A quick and fast intro to Kotlin
A quick and fast intro to Kotlin A quick and fast intro to Kotlin
A quick and fast intro to Kotlin
 
Introduction to Java
Introduction to JavaIntroduction to Java
Introduction to Java
 
Building RESTful applications using Spring MVC
Building RESTful applications using Spring MVCBuilding RESTful applications using Spring MVC
Building RESTful applications using Spring MVC
 
iOS Security
iOS SecurityiOS Security
iOS Security
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring andspringboot training
Spring andspringboot trainingSpring andspringboot training
Spring andspringboot training
 
Spring framework Introduction
Spring framework IntroductionSpring framework Introduction
Spring framework Introduction
 
Introduction à spring boot
Introduction à spring bootIntroduction à spring boot
Introduction à spring boot
 
Swift Programming Language
Swift Programming LanguageSwift Programming Language
Swift Programming Language
 
Java Spring
Java SpringJava Spring
Java Spring
 
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetesk6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
k6: Performance Engineering, Monitoramento e Teste de um HPA no Kubernetes
 

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

🐬 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
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
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
 
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
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
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
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
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
 
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
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
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
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
[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
 
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
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
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
 
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
 

Recently uploaded (20)

🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
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
 
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
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
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
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
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
 
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
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
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...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
[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
 
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
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
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?
 
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
 

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); }