User Tools

Site Tools


Sidebar

General

Python Tutorials

WebGL Tutorials

Node.js Tutorials

Node.js in WebStorm


Martin Christen

View Martin Christen's profile on LinkedIn


Twitter

Timeline of @MartinChristen

MartinChristen avatar

I just signed up as @europython volunteer. Still many spaces available! Do it now! https://t.co/Bam6ZJCjFR
About 1 day, 23 hours ago by: Martin Christen (@MartinChristen)

MartinChristen avatar

@Mr_Robinini I will do a talk about this at @EuroSciPy in August...
About 2 days, 22 hours ago by: Martin Christen (@MartinChristen)

MartinChristen avatar

@Mr_Robinini Try jupyterhub, you can start jupyterlab too (change config file). https://t.co/kDKr9oV946
About 2 days, 22 hours ago by: Martin Christen (@MartinChristen)
node:tutorial11

Node.js Tutorials - Series 1

Tutorial 1.1: C++ && Node

Sometimes it is useful to develop time critical code in C or C++ and then create node.js bindings. In this tutorial we will create some C functions and call them as addons from node.

Prerequisites

It is assumed you already installed the proper development tools required for your operating system:

Linux/MacOS:

  • Python (v2.7.x)
  • make
  • A proper C/C++ compiler toolchain, for example GCC

Windows XP/Vista/7:

  • Python v2.7.x
  • Microsoft Visual Studio C++ 2010

Windows 7/8:

  • Python v2.7.x
  • Microsoft Visual Studio C++ 2012

Node.js uses “GYP” to build projects. GYP means “Generate your projects” and is a project build automation tool originally created by Google. The most prominent usage is building the Chrome browser.

You can install gyp for node.js (“node-gyp”) over npm:

npm install -g node-gyp

Creating the C++ Code

Now we create a new demo project; let's name it “node-cpp-test”!

First we create a new directory “node-cpp-test”:

mkdir node-cpp-test
cd node-cpp-test

in node-cpp-test we create a c++ file “main.cpp” with the following contents:

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

using namespace v8;

Handle<Value> HelloWorld(const Arguments& args) 
{
  HandleScope scope;
  return scope.Close(String::New("Hello World, Greetings from C++"));
}

void init(Handle<Object> exports) 
{
  exports->Set(String::NewSymbol("HelloWorld"),
      FunctionTemplate::New(HelloWorld)->GetFunction());
}

NODE_MODULE(nodecpptest, init)

With the NODE_MODULE Macro we define the module name and its entry point, in our case the module is named “nodecpptest” and the entry function is “init”. In the init function we define the exports of our module. In this example we export the function “HelloWorld”.

In our “HelloWorld” function we define a HandleScope and close it on return. The close function closes the handle scope and returns the value as a handle in the previous scope, which is the new current scope after the call, this is required to ensure the garbage collector will delete the objects properly.

The GYP File

Now we need to create a file called “binding.gyp” which contains the required build information:

{
   "targets" : [
      {
         "target_name": "nodecpptest",
         "sources": ["main.cpp"]
      }
   ]
}

This is a minimal gyp file; the full specification for gyp files is available at: http://code.google.com/p/gyp/wiki/GypLanguageSpecification. In later tutorials we will see more options like linking libraries and other compiler options.

Configuring and Building The Project

After creating this binding.gyp we can start configuring and building:

node-gyp configure

After configuration a “build” directory should be available containing the build files for your compiler and operation system, for example Visual Studio projects under Windows: projects.jpg

Now you can build the example using:

node-gyp build

Creating the Node Application

Now we have compiled our first hello world application. The next step is to create a node application calling our c++ function nodecpptest.

So let's create a node file: “main.js”:

var test = require('./build/Release/nodecpptest');

console.log(test.HelloWorld());

and start the example:

node main.js

Handling Arguments

Now we extend our application to create a function sum which takes 2 or more numbers as argument and returns their sum.

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

  if (args.Length() < 2) 
  {
    ThrowException(Exception::TypeError(String::New("Atleast 2 arguments are required!")));
    return scope.Close(Undefined());
  }
  
  int sum = 0;
  
  for (size_t i=0;i<args.Length();i++)
  {
  	if (!args[i]->IsNumber()) 
    {
      ThrowException(Exception::TypeError(String::New("All arguments must be numbers!")));
      return scope.Close(Undefined());
    }
    
    sum += args[i]->NumberValue();
    
  }
  
  Local<Number> num = Number::New(sum);
  return scope.Close(num);
}

args.Length() contains the total number of arguments. We check if there are atleast 2. Then we iterate through all arguments and check if they are all of type number using the “args[i]→IsNumber()” method. With “args[i]→NumberValue()” we can retrieve an integer and sum up the result. At the end we return a number containing the sum.

Now we have to exend the init function to export the new “Sum” function by the following code:

exports->Set(String::NewSymbol("Sum"),
      FunctionTemplate::New(Sum)->GetFunction());

just recompile the code (node-gyp rebuid) then we test our new function:

var test = require('./build/Release/nodecpptest');

var result = test.Sum(1,2,3,4,5);
console.log(result);

result = test.Sum(10,20);
console.log(result); 

Conclusion

Now we can create C++ functions and call them from node.js! In the next tutorial we will learn how to call JavaScript functions from C++ and return JavaScript specific data types.


node/tutorial11.txt · Last modified: 2013/09/16 22:43 by mchristen