天天看点

nodejs,addon,使用js中传递的函数参数

v8引擎中,js和你自己开发的addon模块,定义在一个上下文中,也就是说它们是相互认识的。这篇文章中我介绍下怎么在addon中,调用js中的函数。

我们先看v8的对象继承关系

nodejs,addon,使用js中传递的函数参数

Function是Value的子类,而js中传给C++的所有函数的类型是Value,所以逻辑上来讲,其实很简单,看文件目录结构

nodejs,addon,使用js中传递的函数参数

building.gyp很简单,如下

{
  "targets": [
    {
      "target_name": "callback",
      "sources": [ "callback.cc"],
      "include_dirs":[]
    }
  ]
}
           

callback.cc是我们的主要代码,看看怎么使用的

#include <node.h>
#include <v8.h>

using namespace v8;

Handle<Value> RunCallback(const Arguments& args) {
    HandleScope scope;
    Local<Function> cb = Local<Function>::Cast(args[0]);    //转换成C++认识的函数
    const unsigned argc = 1;    //我们传递一个参数到js中去
    Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
    cb->Call(Context::GetCurrent()->Global(), argc, argv);  //调用界面传递过来的函数
    return scope.Close(Undefined());    //此函数在js中返回undefined
}

/**
 * 我们把这个模块本身设置为RunCallback函数,也就是说,我们覆盖了模块的exports属性
 */
void Init(Handle<Object> exports, Handle<Object> module) {
    module->Set(String::NewSymbol("exports"), FunctionTemplate::New(RunCallback)->GetFunction());
}

NODE_MODULE(callback, Init)
           

test.js,看我们怎么调用它

var module = require('./build/Release/callback');

var print = function(msg)
{
    console.log(msg);
}

module(print);
           

我们在callback目录下先编译模块

node-gyp configure build
           

再执行test.js

node test.js
           

输出如下

hello world
           

很神奇吧,你不防在java中调用c,再在C中调用java试试,然后你就会体验到nodejs的精华所在,在每一个点,你都有很高的自由度,而又不失效率。

继续阅读