1、先安装node.js和python
2、新建一个demo项目: 创建demo目录,并进入其中,然后运行下面命令。
- mkdir demo
- cd demo
- npm init
运行npm init时,之后会生成一个package.json(具体内容与输入参数有关):
- {
- "name": "demo",
- "version": "1.0.0",
- "description": "a demo for node call native functions",
- "main": "demo.js",
- "scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [
- "node"
- ],
- "author": "Li XianJing",
- "license": "ISC"
- }
3、在项目路径下
- npm install -g node-gyp (全局安装)
- npm install nan 这个也可以用 npm install nan bindings --save
-
-
- 解释
- node-gyp是C++扩展的编译工具;
- nan和bindings包含了C++扩展需要的头文件;
4、用C++编写原生代码( 为了让目录结构整洁一点,我们把代码放到native只目录下)。
下面的文件(native/demo.cc),添加一个Add方法,计算两个数之和:
- #include <nan.h>
-
- void Add(const Nan::FunctionCallbackInfo<v8::Value>& info) {
-
- if (info.Length() < 2) {
- Nan::ThrowTypeError("Wrong number of arguments");
- return;
- }
-
- if (!info[0]->IsNumber() || !info[1]->IsNumber()) {
- Nan::ThrowTypeError("Wrong arguments");
- return;
- }
-
- double arg0 = info[0]->NumberValue();
- double arg1 = info[1]->NumberValue();
- v8::Local<v8::Number> num = Nan::New(arg0 + arg1);
-
- info.GetReturnValue().Set(num);
- }
-
- void Init(v8::Local<v8::Object> exports) {
- exports->Set(Nan::New("add").ToLocalChecked(),
- Nan::New<v8::FunctionTemplate>(Add)->GetFunction());
- }
-
- NODE_MODULE(demo, Init)
5、写一个node-gyp的配置文件(文件名固定为binding.gyp),用来编译C++代码。
- {
- "targets": [
- {
- "target_name": "demo",
- "sources": [ "native/demo.cc" ],
- "include_dirs": [
- "\"require('nan')\")"
- ]
- }
- ]
- }
6、编写一个JS文件(demo.js)),让它调用原生代码。
- var demo = require('bindings')('demo.node')
-
- console.log('add(3, 5) => ', demo.add(3, 5))
7、运行配置脚本(如果没有增删文件,不需要每次运行)
node-gyp configure
8、编译C++程序。
- node-gyp build
- 注意:有修改的时候最好用:node-gyp rebuild
9、运行JS代码,看看是否工作。
node demo.js
其他参考:
- addon其实就是一个桥梁,利用V8提供的API,可以实现JavaScript和C++的互相调用,打通JavaScript和C++之间的接口。
-
- 我们先编写一个小例子,大概了解js层和addon之间数据交换的过程。需要三个文件:
-
- binding.gyp:其实就是一个json文件,因为要使用node-gyp进行编译,该文件可以说是定义了一些编译规则。
- addon.cc: 该文件就是我们需要编写的addon,node-gyp借助vs编译后最终会生成
- addon.node二进制文件。
- index.js: 该文件就是测试js,在js层可以加载addon,调用addon对外的函数。
- void Foo(const v8::FunctionCallbackInfo<v8::Value> &args)
- {
- // from v8 to cpp
- v8::Isolate* isolate = args.GetIsolate();
- v8::String::Utf8Value str(isolate, args[0]);
- std::string cppStr(*str);
-
- // back to v8
- v8::Local<v8::String> v8String = v8::String::NewFromUtf8(isolate, cppStr.c_str(), v8::String::kNormalString);
- }
-
- 1. npm 安装windows-build-tools
-
- cmd管理员模式打开,执行下面命令:
-
- npm install --global --production windows-build-tools
-
- 等待执行完成,重启CMD
-
-
-
-
-
- 2. windows下安装node-gyp
-
- node-gyp就是为node编译c++扩展的时候使用的编译工具。
-
- 安装方法:
-
- npm install -g node-gyp
-
-
-
- 3. 配置依赖
-
- npm config set python python2.7
-
- npm config set msvs_version 2015
-
- 如果不出意外的话我们就可以用node-gyp进行构建了。
-
- 如果出现问题可以参考node-gyp的github主页。
- #include <nan.h>
-
- NAN_METHOD(multi)
- {
- int result = 1;
- for (int i = 0; i < info.Length(); i++)
- {
- result *= info[i]->NumberValue();
- }
- info.GetReturnValue().Set(Nan::New(result));
- }
-
- NAN_METHOD(add)
- {
- int result = 0;
- for (int i = 0; i < info.Length(); i++)
- {
- result += info[i]->NumberValue();
- }
- info.GetReturnValue().Set(Nan::New(result));
- }
-
- void init(v8::Local<v8::Object> exports)
- {
- Nan::SetMethod(exports, "multi", multi);
- Nan::SetMethod(exports, "add", add);
- }
-
- NODE_MODULE(demo, init); // demo-导出模块的名称