舒彩光的互联网生涯
用心做事做人,做最认真的程序员

如何在nodejs中调用c++

2017年09月28日 22:13,by 舒彩光

Nodjs调用c++模块,和调用其他普通nodejs模块一样,使用require()函数。

使用c++编写nodejs模块,你可能需要了解下面的库或API:

v8:这是一个c++库,头文件的路径是:deps/v8/include/v8.h。nodejs 使用v8引擎实现javascript的功能,例如:javascript对象的创建,javascript的函数调用等。

libuv:这是一个C库。Nodejs通过它实现事件循环,工作线程以及平台的异步行为。libuv也可以做为一个跨平台的抽象库,为常见的操作系统提供一个简单,类POSIX的访问,支持许多常见的系统任务,如文件系统,socket,事件循环。libuv还提供类pthread的线程抽象,用来支持更复杂异步插件,超越事件循环。鼓励插件作者使用libuv使用非阻塞的系统操作,工作线程或自定义libuv线程,避免I/O或时间密集型任务阻塞事件循环。

内部Nodejs库:Nodejs导出了一些C++ API供插件开发者使用。其中最重要的是 node::ObjectWrap类。

其他库:如OpenSSL,这些库位于nodejs源码的deps文件夹下,只有V8和OpenSSL符号有意地被Node.js重新导出,并且可以被Addons使用到各种范围。

创建一个Hello World.

代码如下:

#include <node.h>
namespace demo {
using namespace v8;
void Method(const FunctionCallbackInfo<Value>& args) {
	Isolate* isolate = args.GetIsolate();
	args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
}

void init(Local<Object> exports) {
	NODE_SET_METHOD(exports, "hello", Method);
}

NODE_MODULE(NODE_GYP_MODULE_NAME, init)
}

Nodejs必须包括一个初始化函数:

void init(Local<Object> exports);

然后用NODE_MODULE将初始化函数注册到Nodejs:

NODE_MODULE(NODE_GYP_MODULE_NAME, init)

注意NODE_MODULE不是函数,后面没有分号。

编译:

当代码写好后,它必须编译成二进制文件。我们必须在项目的根目录写一个名为binding.gyp的文件。这个文件是JSON格式,用于描述如何编译文件:

{ "targets": [ { "target_name": "addon", "sources": [ "hello.cc" ] } ] }

如上所示,addon表示编译后的目标文件名(addon.node).

现在所有代码都准备好了,需要一个编译工具:node-gyp,在控制台输入 npm install node-gyp -g 安装。

所有这些都准备好了。打开控制台,输入命令node-gyp configure,将在项目文件夹下生成一个build文件夹(在linux 操作系统下会包含makefile文件,在windows操作系统下包含vcxproj文件)。

接下来输入node-gyp build命令将会编译c++文件。本示例中将会生成一个addon.node文件到build/Release文件夹。

测试:

在build/Release文件夹下新建一个文件test.js:

const addon = require('./addon'); 
console.log(addon.hello());

输入node test.js 运行后,输出 World!