Category Archives: NodeJS

Returning array of C++ wrapped objects to NodeJS and JavaScript using nan

Lately I had a hard time trying to figure out how to properly wrap simple C++ objects (like structs or so) with limited understanding of object-oriented JS. So I took some time (actually not so long, but sill) and found out that there are no classes in JS so constructing objects is quite tricky as it always use prototype function.

Don’t really like the idea, but well…

Anyway, it was not really straightforward at the beginning to wrap C++ object. A bit easier after figuring out all that function for objects creation. It ends up with creating new wrapping object that has a creating function (I have called it “constructor” using the same naming as in the documentation. My objects are read only (in fact it is a representation of serial devices) and all properties are also read only, so I had to create only getters, called accessors:

So the whole “constructor” template function looks like this:

Then for each getter you can create a method (I liked this way) or create one getter and use the name to distinguish return values. For me it looked like this:

So the last thing is to create the JS object from the C++ object and fill the array. First object creation:

When we do have this we just need to create an JavaScript array with nan and v8:

That’s all, final result looks like this in console:

As always you can see the whole code as a commit on the github:

https://github.com/killpl/obd_cougar/commit/84974d028f5b2669e41db8b4c0ecd54b3d4ebb1b

After finally resolving this problems it is time to go on with UART communication and sending some commands to ELM327 😉

NodeJS addon with C++ and Objective-C

I have finished the module a few days ago (and it does not work, check the previous post) so now it is a good time to show a bit of technical difficulties and solutions.

First things first – an introduction. What we want is a class (I think in JS more proper name is a  prototype) with a few methods:

  • StartScan – with callback for results.
  • StopScan
  • IsScanning
  • GetState – current state of bluetooth (on/off etc).

We start with a module file – obd_cougar_lib.cc, structure of binding.gyp was described before for that project so I won’t paste it again, this is the file:

https://github.com/killpl/obd_cougar/blob/master/cougar_bluetooth_lib/binding.gyp

I used nan as the whole internet recommended and ended with something like this:

Let’s divide it into parts and describe one by one. First we need a module to export information and module initialization information. First says what we want to export and second is a static function that creates that object:

We use two defines to achieve this – NODE_MODULE  with two parameters: module name and second is initialization function conveniently declared by macro NAN_MODULE_INIT  with one parameter – a name. We export here a class and a function – we don’t have to export just a one thing.

Then we need a class to export – let’s call it Cougar_Bluetooth and init from inside of Init – this is visible in the snippet above. Next create a class:

There  static NAN_MODULE_INIT(Init) method which initializes class by setting a class name with

and constructor (the “new” method) with:

Of course we need methods inside the class too:

Method static NAN_METHOD(New) is our constructor, but in JavaScript we have to take care also for the possibility of using the constructor without the new operator – we just call the constructor with provided arguments in that case. Also we have a static field to hold that constructor. There we use a trick to avoid initialization in another file – we don’t need this if it is static variable in static method, so we return a reference to that object:

Last but not least I will show you how we can create a method in the class, this time descriptions will be inline in code:

That’s all. I have tested callback with simple logger class (to log messages from the addon to JS console) and it works. There were no callback calls for scan, because my devices are not BLE.

Seems quite easy at this point, but believe me – it wasn’t. At least it is not when you don’t have a code that you can copy and paste or clone.

Binding.gyp file for Objective-C++ project built using XCode

Hi!

Last time we started with the project and I promised that next will be an addon. I don’t have it finished yet, but stepped into an unknown teritory of configuring everything to compile and link find with an Objective-C(++) code and native macOS libraries: CoreBluetooth and CoreFoundation.

There are not many informations at all on the internet about how to make it work so I had to do a lot of guessing and trying.

First I made a rookie mistake (I am a newbie with Node addons so no surprise here) and added include_dirs at the wrong level of the file. Which made it unusable for both Xcode and node-gyp.

And I spent a few hours just setting it manually in Xcode settings (some of node-gyp commands remove the project file, node-gyp rebuild  for example, or just node-gyp clean ) before I found the problem.

I was really pissed off at the moment when I have found out that most of settings that I put there were just not parsed at all because there were not added as a child element of target.

Anyway.

We need to build on OS X using native libraries. I wanted to use Objective-C too just to try how it works. So first we may add .m and .mm files (.m is Objective-C, .mm is Objective-C++ – there is not much difference between them, second just allows C++ code inside) so my “sources” now looks like this:

Of course it won’t work now. We need to change at least two more things. First (this is not mandatory, but I really recommend that) we add conditional settings based on operating system. This way we will not break compile on another platforms in the future:

Then we populate the “mac”:

Notice how libraries are imported (“link_settings”). Somehow for one library it is:

It does not work for more than one though, tried using comma etc. The way I put it works.

Next thing is CLANG_CXX_LIBRARY which means I can use C++11 and -ObjC++ which tells the compiler that some of the code will be in Obj-C.

Now also project created with this command works and can be built using Xcode:

This works fine so I will now try to finish the library and add some logging possibility. Stay tuned 😉

Let’s start with C++ NodeJS addon

First things first – I know literally nothing about NodeJS C++ addons. I have an experience with C++ and with interopearation between C+++ and other languages, but not JavaScript and definitely not NodeJS (except small, top-secret project in bozon).

So we are going to learn together ;] Happy?

Let’s get started with getting project structure prepared – current architecture divides the project into (at least) three layers, which makes it kind of “Buissness Logic Desing Pattern”:

  • JavaScript / HTML presentation layer.
  • JS / NodeJS thin proxy as a business logic.
  • C++ addon for NodeJS for whole OBD2 protocol and connection.

The first layer has to run on desktop – which does not often happen for JS apps. That’s where Electron kicks in. It is a framework for building desktop apps with NodeJS, HTML and CSS, which nicely fits my needs.

Sometimes I am actually a lazy person and don’t like to create whole project structure by hand, so for that I’ve been using Bozon. It is not perfect, but creates a project scaffolding with build script, run script and unit testing script (created with Gulp, whatever this is). Exactly what I need, everything else I can do myself. You can see it created yourself in this commit.

Okay, enought about libraries, let’s start with creating NodeJS addon in C++, so we can see how it works.

First we create a source code of our binding layer file as described in documentation:

Then we have to create a binding.gyp describing build configuration:

At the end install and run the node-gyp:

Now we have a scaffolding for the C++ plugin which can be easily built. There is one more thing actuall, I don’t like writing C++ in the notepad, so I wanted to have an XCode project and this is quite easy to do with one command:

Clever. The build does not work without node-gyp configure ran after though.

Then we want nan module which creates an abstraction between v8 and node version and our C++ code. I wanted to do this myself, but there is no need to reinvent the wheel:

And change our bindings file, there should be added information about include directories:

Now every use of #include <node.h>  should be replaced with #inlcude <nan.h> .

Also if you use like me Xcode you need to edit project “binding.xcodeproj” and add to search paths nan directory:

Also we will in the future have more than one NodeJS library so we might want some common code – path to headers should be added the same way.

This is all for now, in next post we are going to try this with bluetooth enumeration on macOS and think about why node-gyp does not create proper project with HEADER_SEARCH_PATHS.