How to Use a C++ Library from Node.Js

How can I use a C++ library from node.js?

Look at node-ffi.

node-ffi is a Node.js addon for loading and calling dynamic libraries using pure JavaScript. It can be used to create bindings to native libraries without writing any C++ code.

Call C code from node.js

The nodeffi seems to be simplest way to do that.
I didn't test it so it can has problems that I don't realize now.

But I would suggest to do something like that, following the tutorial.
Install nodeffi:

Generate a library for your bus-driver if you don't have one, let's call it libbusdriver.

Then in your javascript do something similar to this:

var ffi = require('ffi');

var libbusdriver = ffi.Library('libbusdriver', {
'bus_init': [ 'void', [ 'void' ] ],
'bus_write': [ 'void', [ 'string' ] ],
});
libbusdriver.bus_init();
libbusdriver.bus_write("Hello");

Let me know if it helps.

Node.js add on module in C/C++

In JS:

Create a class that inherits from EventEmitter. Doing this you'll be able to listen to events from this class.

If you call your addon's function with a callback from this class and in the callback you emit your event you can achieve what you want.

Something like this:

const test = require("./build/Release/test");
const EventEmitter = require('events');

class Test extends EventEmitter {
constructor() {
super();
this.addon = test;
}

test() {
test.hello("Simon", (data) => {
this.emit("testEvent", data);
});
}
}

const myTest = new Test();

myTest.on("testEvent", (data) => {
console.log("testEvent says: ", data);
})

myTest.test();

In C++:

Based on the example found here, you can add an AsyncWorker that will process your data in the background and call a callback once finished.

Like this:

#include <napi.h>
#include <iostream>
#include <string>
#include <chrono>
#include <thread>

using namespace Napi;

class TestWorker : public AsyncWorker {
public:
TestWorker(Function& callback) : AsyncWorker(callback) {}

void Execute() override {
std::this_thread::sleep_for(std::chrono::seconds(1));
}

void OnOK() override {
HandleScope scope(Env());
Callback().Call({String::New(Env(), "message from the addon")});
}
};

You can provide this callback as an argument to your hello function along with your current argument "Simon".

Your code extended with the callback argument and the starting of the AsyncWorker:

 Napi::String hello(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
std::string strResult = "Hello ";
strResult += info[0].ToString();
Function cb = info[1].As<Function>();
TestWorker* wk = new TestWorker(cb);
wk->Queue();
return Napi::String::New(env, strResult);
}

Expose c-library functionality to node

The problem was communication between C++ and C. In above case a C header file was included in C++ code. Compile was expecting the C++ code. So on compiling linker was got choked due to mismatch in compiled code.

So I used the extern "C" directive to tell the compiler about C header files by following code.

extern "C" {
#include "bibutils.h"
#include "bibprogs.h"
}

Is it possible to use a c++ library in a javascript application

Yes. You can utilize emscripten to convert C++ to JavaScript. You can alternatively

  • use Native Messaging to communicate with a shell script

  • use a local server to POST commands to a shell script which runs the native shell script, e.g., see shell_exec() calls at PHP at How to programmatically send a unix socket command to a system server autospawned by browser or convert JavaScript to C++ souce code for Chromium?



Related Topics



Leave a reply



Submit