首页 > Personal > H5 > electron 调用nodejs native c++ addon
2016
07-24

electron 调用nodejs native c++ addon

前面一篇文章说明了如何搭建electron桌面应用,因为项目中会用到第三方的c++ dll,网上能找到的文章也不多,所以这里介绍一下,这篇文章先说明如何调用nodejs的native addon。
基于上一篇文章搭建的项目,先搭建使用nodejs native 插件的例子,nodejs native addon需要用的node-gyp,使用google v8中使用的gyp来编译项目,关于gyp之前有过一定了解,这里就不做叙述了,网上虽然资料不多,但是还是能够查得到的。

创建文件hello.cc
#include <node.h>
#include <v8.h>
using namespace v8;
void Method(const v8::FunctionCallbackInfo<Value>& args) {
Isolate* isolate = Isolate::GetCurrent();
HandleScope scope(isolate);
args.GetReturnValue().Set(String::NewFromUtf8(isolate, ” nodejs native hello world “));
}

void Init(Handle<Object> exports) {
Isolate* isolate = Isolate::GetCurrent();
exports->Set(String::NewFromUtf8(isolate, “hello”),
FunctionTemplate::New(isolate, Method)->GetFunction());
}

NODE_MODULE(hello, Init)

创建文件binding.gyp,用于node-gyp编译项目
{
“targets”: [
{
“target_name”: “hello”,
“sources”: [ “hello.cc” ]
}
]
}

创建文件hello.js,来调用native addon内容
var addon = require(‘bindings’)(‘hello’);
console.log(addon.hello()); // ‘ nodejs native hello world ‘

里面的require(‘bindings’),需要用到模块bindings,使用命令安装
npm install -g bindings
如果不使用require(‘bindings’),可以用下面的代码替换
var addon = require(‘./build/Release/hello’);
工程生成的文件会输出到文件夹build/Release/中,bindings会自动处理相关文件夹位置,用起来更方便。

创建文件package.json,描述项目
{
“name”: “hello_world”,
“version”: “0.0.0”,
“description”: “node.js native addon”,
“main”: “hello.js”,
“private”: true,
“scripts”: {
“start”: “node hello.js”
},
“gypfile”: true,
“dependencies”: {
“bindings”: “~1.2.1”
}
}

安装node-gyp,用于编译
npm install -g node-gyp

配置编译工程
node-gyp configure build

运行查看结果
npm run start

每次修改c++文件后需要,重新编译项目
node-gyp build
如果修改了c++文件结构,还需要重新配置项目
node-gyp configure build

如果使用npm install 安装nodejs包的话,回调用node-gyp rebuild,可能会出现报错,没有关系,生成好node_modules后,在调用node-gyp configure build,就可以运行了。

相关代码可以在 https://github.com/wy182000/electron_nodejs_native_addon.git下载查看。

另外还可以使用nan模块通过封装来编写v8 c++代码,hello.cc如下
#include <nan.h>

void Method(const Nan::FunctionCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(Nan::New(” nodejs native hello world “).ToLocalChecked());
}

void Init(v8::Local<v8::Object> exports) {
exports->Set(Nan::New(“hello”).ToLocalChecked(),
Nan::New<v8::FunctionTemplate>(Method)->GetFunction());
}

NODE_MODULE(hello, Init)

修改binding.gyp
{
“targets”: [
{
“target_name”: “hello”,
“sources”: [ “hello.cc” ],
“include_dirs”: [
“<!(node -e \”require(‘nan’)\”)”
]
}
]
}
这里使用的node -e “require(‘nan’)”输出的文件夹。

修改package.json
{
“name”: “hello_world”,
“version”: “0.0.0”,
“description”: “node.js native addon”,
“main”: “hello.js”,
“private”: true,
“scripts”: {
“start”: “node hello.js”
},
“gypfile”: true,
“dependencies”: {
“bindings”: “~1.2.1”,
“nan”: “^2.4.0”
}
}

需要安装nan模块
npm install -g nan

npm install
node-gyp configure build
npm run start

代码可以在 https://github.com/wy182000/electron_nodejs_native_addon_nan.git下载。
更多的nodejs addon还可以在https://github.com/nodejs/node-addon-examples中找到。

native addon 建好了,下面就可以在electron中调用了。
基于之前的electron项目,把上面建好的native addon 文件夹改名为hello放入node_modules文件夹中,
并修改hello.js
var addon = require(‘bindings’)(‘hello.node’);

exports.hello = function () {
return addon.hello();
}
进入node_modules\hello文件夹,重新使用electron 编译项目(如果使用默认编译的.node文件,electron可以运行,但是会提示dll 错误)
node-gyp rebuild –target=1.2.8 –arch=x64 –dist-url=https://atom.io/download/atom-shell
这里–target填写electorn的版本号,–dist-url说明从electron的网站获取头文件和lib。在这里下载相关文件经常会下载失败,文件会下载到用户目录的.node-gyp文件加下,如上面配置的话会下载到iojs-1.2.8文件夹,在文件夹中SHASUMS256.txt如果下载成功后,会看的到有那些文件需要下载,配合显示的下载地址添加文件名用迅雷下载再解压到该文件夹,可以解决下载问题,再次运行命令编译会忽略下载。

编译好以后,修改electron项目的index.html,在<body></body>范围内添加
<p>
<script>
var addon = require(“hello”);
document.write(addon.hello());
</script>
</p>

运行就可以查看显示内容了。

相关代码可以在https://github.com/wy182000/electron_nodejs_native_addon.git中下载。
另外,一个小贴士,在git 的gitignore中如果在忽略的文件夹中不忽略某些内容可以在内容前加上!表示,但是在忽略的定义中一定要在后面加上*,不然不忽略就会失效,也是研究了好久才弄对的,如
node_modules/*
!node_modules/hello/

最后编辑:
作者:wy182000
这个作者貌似有点懒,什么都没有留下。