[英]Calling JavaScript from C++ with node.js
有没有办法从C ++通过node.js调用JS函数(作为回调或类似的东西)? 如果有,怎么样? 我在网上搜索它,但没有找到任何有用的资源。
提前致谢
答案是肯定的,这是一种方法:
我创建了一个名为index.js的js文件,这里是文件的路径
D:\NodeJS\call_js_from_cpp
它包含以下代码
console.log("hello");
现在我有一个C ++代码执行以下shell命令并将输出存储在变量“output”(这是一个字符串)中:
node D:\NodeJS\call_js_from_cpp\index.js
这是C ++代码:(请注意,在代码中,路径中有双\\,因此它变得像这个节点D:\\ NodeJS \\ call_js_from_cpp \\ index.js)
#include<iostream>
#include<fstream>
#include<string>
#include<cstdlib>
#include<sstream>
std::string ssystem (const char *command) {
char tmpname [L_tmpnam];
std::tmpnam ( tmpname );
std::string scommand = command;
std::string cmd = scommand + " >> " + tmpname;
std::system(cmd.c_str());
std::ifstream file(tmpname, std::ios::in );
std::string result;
if (file) {
while (!file.eof()) result.push_back(file.get());
file.close();
}
remove(tmpname);
return result;
}
//for cygwin
int main(int argc, char *argv[])
{
std::string bash = "node D:\\NodeJS\\call_js_from_cpp\\index.js";
std::string in;
std::string s = ssystem(bash.c_str());
std::istringstream iss(s);
std::string output;
while ( std::getline(iss, output) )
{
std::cout << output;
}
return 0;
}
构建本机插件的一种方法是使用提供的函数作为回调,例如,让我们假设您在本机环境中声明了一个名为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
当然可以。 例如,如果你想在C++
编写一个简单的阶乘函数,你可以做类似的事情
#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)
在您的JavaScript
文件中,像这样调用它
var factorialAddon = require('./addons/Factorial');
factorialAddon.factorial(5, function (result) {
console.log(result);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.