nodejs extension in D (with some help from C++)
Ervin Bosenbacher
ervin.bosenbacher at gmail.com
Fri Jan 5 11:47:07 UTC 2018
Hi
Just wanted to share how I have managed to interface node.js with
D using C++ bridge and NAN. So far I have been using C++ and rust
for this but for obvious reasons (that would be a long story to
explain) I wanted to go with D. One of the show stoppers was the
lack of well established (or I don't know if that exists) library
of framework to help with that.
Anyway I have managed to do this using information gathered from
various places and I wanted to share if anyone runs into the same
issue.
First I created a d lib using dub.
Simple code for the library:
import std.string;
extern (C++) immutable(char)* D_func(const char *s) {
import std.string;
return toStringz(fromStringz(s) ~ "-response");
}
Code for the c++ file which is the interface to the node.js
#include <nan.h>
char *D_func(const char *);
extern "C" int rt_init();
extern "C" int rt_term();
// NAN_METHOD is a Nan macro enabling convenient way of creating
native node functions.
// It takes a method's name as a param. By C++ convention, I used
the Capital cased name.
NAN_METHOD(Hello) {
// send this to D code
const char *s = "request";
// Initialize the D runtime
rt_init();
// Create an instance of V8's String type
auto message = Nan::New(D_func(s)).ToLocalChecked();
// Shut down D
rt_term();
// 'info' is a macro's "implicit" parameter - it's a bridge
object between C++ and JavaScript runtimes
// You would use info to both extract the parameters passed
to a function as well as set the return value.
info.GetReturnValue().Set(message);
}
// Module initialization logic
NAN_MODULE_INIT(Initialize) {
// Export the `Hello` function (equivalent to `export
function Hello (...)` in JS)
NAN_EXPORT(target, Hello);
}
// Create the module called "addon" and initialize it with
`Initialize` function (created with NAN_MODULE_INIT macro)
NODE_MODULE(addon, Initialize);
finally the binding.gyp that links the whole thing together and
builds the Node.js extension.
the binding.gyp
{
"targets": [
{
"include_dirs": [
"<!(node -e \"require('nan')\")"
],
"target_name": "addon",
"sources": [ "main.cpp" ],
"libraries": [ "-L/path/to/dlang_library",
"-ldlang_library",
"-L/path/to/phobos/library", "-lphobos2" ]
}
]
}
and the package.json
```
{
"name": "call_d_from_nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"compile": "node-gyp rebuild",
"start": "node main.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"nan": "^2.8.0",
"node-gyp": "^3.6.2"
}
}
```
enjoy, any questions let me know. :)
More information about the Digitalmars-d
mailing list