有没有一种方法可以通过node.js从C++中调用JS函数(作为回调或类似于此的方式)? 如果有,如何实现? 我正在网上搜索,但没有找到任何有用的资源。
提前感谢。
有没有一种方法可以通过node.js从C++中调用JS函数(作为回调或类似于此的方式)? 如果有,如何实现? 我正在网上搜索,但没有找到任何有用的资源。
提前感谢。
一种从本地插件中实现的方法是使用提供的函数作为回调函数,例如假设您在本地环境(本地插件)中声明了一个名为 setPrintFunction()
的函数:
(例如,将其命名为 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)
index.js )
const { setPrintFunction } = require('<your path to .node file>');
function printNodeMsg(msg) {
console.log('<msg>: ' + msg);
}
setPrintFunction(printNodeMsg);
你所做的基本上是获取对 v8::Function
的引用(即javascript函数,但在本机环境中),然后调用它并将"Hello World!"
作为第一个(唯一)参数传递。
更多相关信息请参阅: https://nodejs.org/api/addons.html
std::string
传递给C++函数,该函数将被传递到其JavaScript对应部分。 - plasmacelprintNodeMsg(msg)
,我想从C++中调用它并将msg
参数传递给它。插件不是问题,但我希望能够传递参数,而不仅仅是调用函数。因此,调用C++函数void printNodeMsg(const std::string& msg)
将在JS站点上调用prontNodeMsg(msg)
,传递指定的字符串数据。 - plasmacel#include <node.h>
using namespace v8;
int factorial(int n) {
if (n == 0) return 1;
else return n * factorial(n - 1);
}
void Factorial(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
if (args.Length() != 2) {
isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong number of arguments")));
} else {
if (!(args[0]->IsNumber() && args[1]->IsFunction())) {
isolate->ThrowException(Exception::TypeError(String::NewFromUtf8(isolate, "Wrong arguments type")));
} else {
int result = factorial(args[0]->Int32Value());
Local<Function> callbackFunction = Local<Function>::Cast(args[1]);
const unsigned argc = 1;
Local<Value> argv[argc] = { Number::New(isolate, result) };
callbackFunction->Call(isolate->GetCurrentContext()->Global(), argc, argv);
}
}
}
void Init(Handle<Object> exports) {
NODE_SET_METHOD(exports, "factorial", Factorial);
}
NODE_MODULE(Factorial, Init)
var factorialAddon = require('./addons/Factorial');
factorialAddon.factorial(5, function (result) {
console.log(result);
});