v8引擎中,js和你自己開發的addon子產品,定義在一個上下文中,也就是說它們是互相認識的。這篇文章中我介紹下怎麼在addon中,調用js中的函數。
我們先看v8的對象繼承關系
Function是Value的子類,而js中傳給C++的所有函數的類型是Value,是以邏輯上來講,其實很簡單,看檔案目錄結構
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的精華所在,在每一個點,你都有很高的自由度,而又不失效率。