Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling JavaScript from C++ with node.js

Tags:

Is there a way to call JS functions from C++ through node.js (as callbacks or something like that)? If yes, how? I'm searching for it on the web, but haven't found any helpful resource.

Thanks in advance

like image 356
plasmacel Avatar asked Mar 20 '15 11:03

plasmacel


People also ask

Can you call a JavaScript function from C #?

For calling C# method from JavaScript you can use ScriptManager or jQuery . I personally use jQuery . You need to decorate the method that you want to call from JavaScript with WebMethod attribute. For more information regarding calling C# method (called PageMethod ) from jQuery you can refer to Dave Ward's post.

Can I use C in JavaScript?

It is possible to implement a C API in JavaScript! This is the approach used in many of Emscripten's libraries, like SDL1 and OpenGL. You can use it to write your own APIs to call from C/C++.

Does Node.js use C++?

Yes, Node. js has a great portion of it written in C/C++ and a lot of its modules are actually implemented in C/C++. Just like any other javascript project out there, Node. js internally has a collection of dependencies that it uses to actually execute your code.


1 Answers

One way to do it form a native addon can be using the provided function as a callback, for example let's gonna assume that you have a function named setPrintFunction() declared in your native environment (A native addon):

(Call this for example main.cc)

#include <node.h> #include <string>  v8::Persistent<v8::Function> fn;  // Call this at any time, but after the capture! void printToNode(std::string msg) {   auto isolate = fn->GetIsolate();   // This part is the one that transforms your std::string to a javascript   // string, and passes it as the first argument:   const unsigned argc = 1;   auto argv[argc] = {       v8::String::NewFromUtf8(isolate,                           msg.c_str(),                           v8::NewStringType::kNormal).ToLocalChecked()   };   cb->Call(context, Null(isolate), argc, argv).ToLocalChecked(); }  // This is your native function that captures the reference void setPrintFunction(const v8::FunctionCallbackInfo<Value>& args) {   auto isolate = args.GetIsolate();   auto context = isolate->GetCurrentContext();   auto cb = v8::Local<v8::Function>::Cast(args[0]);   fn = v8::Persistent<v8::Function>::New(cb); }  // This part exports the function void Init(v8::Local<v8::Object> exports, v8::Local<v8::Object> module) {   NODE_SET_METHOD(module, "exports", setPrintFunction); }  NODE_MODULE(NODE_GYP_MODULE_NAME, Init) 

Then, just importing your addon and using it like:

(Call this for example index.js)

const { setPrintFunction } = require('<your path to .node file>');  function printNodeMsg(msg) {   console.log('<msg>: ' + msg); }  setPrintFunction(printNodeMsg); 

So what you're basically doing is capturing the reference to the v8::Function (Which is the javascript function, but in the native environment) and then invoking it and passing "Hello World!" as the first (and unique) parameter.

More on the subject: https://nodejs.org/api/addons.html

like image 55
SigmaSoldier Avatar answered Oct 22 '22 04:10

SigmaSoldier