把 JavaScript 函数传入到一个 C++ 函数并在那里执行它们,这在插件里是常见的做法。 以下例子描述了如何调用这些回调:
// addon.cc#include <node.h>namespace demo {using v8::Context;using v8::Function;using v8::FunctionCallbackInfo;using v8::Isolate;using v8::Local;using v8::Null;using v8::Object;using v8::String;using v8::Value;void RunCallback(const FunctionCallbackInfo<Value>& args) {Isolate* isolate = args.GetIsolate();Local<Context> context = isolate->GetCurrentContext();Local<Function> cb = Local<Function>::Cast(args[0]);const unsigned argc = 1;Local<Value> argv[argc] = {String::NewFromUtf8(isolate,"hello world").ToLocalChecked() };cb->Call(context, Null(isolate), argc, argv).ToLocalChecked();}void Init(Local<Object> exports, Local<Object> module) {NODE_SET_METHOD(module, "exports", RunCallback);}NODE_MODULE(NODE_GYP_MODULE_NAME, Init)} // namespace demo
注意,该例子使用了一个带有两个参数的 Init(),它接收完整的 module 对象作为第二个参数。
这使得插件可以用一个单一的函数完全地重写 exports,而不是添加函数作为 exports 的属性。
为了验证它,运行以下 JavaScript:
// test.jsconst addon = require('./build/Release/addon');addon((msg) => {console.log(msg);// 打印: 'hello world'});
在这个例子中,回调函数是被同步地调用。
