Recalling node.js function from C ++

I am trying to configure a C ++ application that should be able to call a function that is part of the node.js module

While I could find sample code on how to create C ++ add-ons for node.js, as well as some examples of how to call V8 code from C ++, I did not come across something like calling a node.js function from C ++

I suggest that ideally the approach would be

  • Setting up the node.js environment, for example. compile all necessary modules once
  • When a C ++ application is required, call one of the available node.js functions with arguments
  • Reading and processing function return values

Ideally, the node.js code and the C ++ code are executed in the same process context, so there is no need to sort the arguments and return values ​​according to some type of stream abstraction.

All tips are welcome!

Th

Peter

+4
source share
1 answer

In the end, I managed to do something

What I struggled with the most was how to handle the node / v8 event loop so that it starts when the javascript function is called, but also stops when the javascript function is executed, so that the C ++ call method continues ... basically wait until the whole asynchronous processing node.

In short, what I did is edit a C ++ class that does something in strings

  • Initialize the node first, as in the node.cc methods Node :: Init and Node :: Run and pass an argument pointing to the node script that defines the function I want to call

  • Then register the C ++ function in the global node namespace, which will be used by the javascript function as the final callback. More or less like

    v8::Locker locker; v8::HandleScope handle_scope; v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); global->Set(v8::String::New("functionCallback"), v8::FunctionTemplate::New(fnCallback,v8::External::Wrap(this))); 
  • Then call the javascript function

     v8::Handle<v8::Value> value = global->Get(v8::String::New(functionName.c_str())); v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(value); v8::Handle<v8::Value> *v8Args = new v8::Handle<v8::Value>[functionArguments.size()]; for (std::vector<std::string>::const_iterator it = functionArguments.begin(); it != functionArguments.end(); ++it) { int ix = distance(functionArguments.begin(),it); v8Args[ix] = v8::String::New((*it).c_str()); } v8::Handle<v8::Value> fnResult; fnResult = func->Call(global, functionArguments.size(), v8Args); uv_run(uv_default_loop(),UV_RUN_DEFAULT); 
  • It is important that the javascript function called calls the global callback, as in (javascript)

     global.functionCallback(result); 
  • This callback (C ++) will save the result and end the event loop

     static v8::Handle<v8::Value> fnCallback(const v8::Arguments& args) { ... // Stop node event loop so that the "calling" app continues (loop is started in execFn) uv_stop(uv_default_loop()); ... 

I understand that this is a bit complicated. If anyone is interested, I can share the C ++ class, but my knowledge of C ++ / v8 / node is very limited, so I would prefer not to publish it completely

Peter

+5
source

Source: https://habr.com/ru/post/1486469/


All Articles