digitalmars.D - nodejs extension in D (with some help from C++)
- Ervin Bosenbacher (89/89) Jan 05 2018 Hi
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. :)
Jan 05 2018