In this article I will guide you on how to write a native module for node.js in Windows using Visual Studio.
About the example
In this example we are going to build a module to log events to the Windows Event Log. The project is already published in  github and you can install it with npm.
I like it, but why native?
I don't speak c++
The code that I am going to show well... it might have several problems. The thing is that my c++ skills are close to my English skills. I can read it and I can write it but as Russ Olsen say (for ruby) I have not absorb the "c++ way" of thinking and problem solving. So, please if you think that something could be improved just tell me.
C++/CLI is a Microsoft's evolution of the c++ language invented by Bjarne Stroustrup. The name is a tuple "C++" and "CLI", CLI means "Command Language Infrastructure" which is the specification for the .Net framework. So, you can think of c++/cli as:
- The way you write c++ for the .Net framework
- Interoperability between the c++ model and the .net framework In this examples I will use the .Net class System.Diagnostic.EventLog.
Configuring the environment
The first thing you will need to do is to download the Node.js source code and uncompress it somewhere in your disk. Then you will have to build the source code by running the vcbuild.bat file. Note: the build process needs python 2.x installed and it should be accesible from the path.
Creating the project in Visual Studio
1-Create a new "CLR Empty Project":
2-Do these changes to the project settings:
3-Add these directories to the Include Directories (remember to change C:\node-v0.6.14\ with the path where you have the node.js sources)
4-Change the Libraries Directories as follows:
5-Add a new "C++ File (.cpp)" called "EventLog", so your solution has to look as:
Note: that the cpp file that we add has to be /CLR.
Show me the code
Nitpicker corner: Don't get overwhelmed! I wrote some comments in the source to explain the different pieces:
Some interesting things about this:
- Node will call always the static methods of the class, the New and the Log.
- In the statics methods we have to unwrap/wrap the "this" to get/st the real instance of the class (c++ instance).
- We store the _eventLog instance in a private non static field.
Testing the module
When you generate this project, you will have a "debug" folder at the same level than the solution (note that is not the debug folder of the project folder). There is one important file there, the ".node" file which is a dll than node can talk to. Now, if you can open a command line prompt and try the stuff with the node REPL, but remember that in order to write to the event log you need an elevated prompt, otherwise will happen this:
So, you run cmd.exe as an administrator, go to the solution folder \debug and do this:
Then if you open the event log you will see this:
You can debug your module from visual studio (that's crazy). First you need to be running Visual Studio as an admin, this is not always, it is because we are running the node's REPL as an admin in order to write to the event log. Once you have done the "require" call in the node REPL, go to the Debug menu of Visual Studio and then "Attach to Process" and look at the node process:
Then you can set breakpoints and this will happen:
As you can see here we are executing the eventLog.WriteLog method in the same thread. An standard for this is to open a new thread using "uv". I will explain this in another article later.
- I have used this guide example from Saar Yahalom as starting point.