繁体   English   中英

使用node.js从C ++调用JavaScript

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM