NodeJS C/C++扩展之Hello World~

来源:互联网 发布:淘宝内部优惠券广告语 编辑:程序博客网 时间:2024/06/05 00:16
先看官方文档

Addons

Node.js Addons are dynamically-linked shared objects, written in C or C++, that can be loaded into Node.js using the require() function, and used just as if they were an ordinary Node.js module. They are used primarily to provide an interface between JavaScript running in Node.js and C/C++ libraries.
Node的插件是动态连接到共享对象上的,可以使用C/C++编写,并能够使用require()语法,使用方法类似于其他的npm模块。Node插件主要用于提供一个接口,使得Javascript能够使用到C/C++类库。
At the moment, the method for implementing Addons is rather complicated, involving knowledge of several components and APIs :
目前,实现插件的方法相当复杂,涉及到多种组件和API的知识:
· V8: the C++ library Node.js currently uses to provide the JavaScript implementation. V8 provides the mechanisms for creating objects, calling functions, etc. V8’s API is documented mostly in the v8.h header file (deps/v8/include/v8.h in the Node.js source tree), which is also available online.
· V8:C++类库,NodeJS可以使用之以提供Javascript实现。V8提供了一个机制来创建对象,调用函数等。V8的API文档描述大部分在其头文件v8.h中已经写明,并且能够在线获得。
· libuv: The C library that implements the Node.js event loop, its worker threads and all of the asynchronous behaviors of the platform. It also serves as a cross-platform abstraction library, giving easy, POSIX-like access across all major operating systems to many common system tasks, such as interacting with the filesystem, sockets, timers and system events. libuv also provides a pthreads-like threading abstraction that may be used to power more sophisticated asynchronous Addons that need to move beyond the standard event loop. Addon authors are encouraged to think about how to avoid blocking the event loop with I/O or other time-intensive tasks by off-loading work via libuv to non-blocking system operations, worker threads or a custom use of libuv’s threads.
· libuv:一个C类库,提供Node.js事件循环,其工作线程和所有基于平台的异步行为的实现。同时它作为一个跨平台的抽象库,提供简单,类可移植方式访问所有主流操作系统以及许多常见的任务,例如文件系统交互、套接字、定时器和系统事件。libuv同样也提供了类多线程抽象,可以用于更复杂的需要突破标准事件循环的异步插件。插件作者被鼓励去思考如何避免在执行I/O或其他耗时任务时阻塞事件循环,通过使用libuv均衡负载从而不会阻塞操作系统,工作线程或一个用户使用的libuv线程。
· Internal Node.js libraries. Node.js itself exports a number of C/C++ APIs that Addons can use — the most important of which is the node::ObjectWrap class.
· Node.js内部类库。Node.js自身暴露一系列C/C++的API从而插件能够使用——其中最重要的是node::ObjectWrap这个类。
· Node.js includes a number of other statically linked libraries including OpenSSL. These other libraries are located in the deps/ directory in the Node.js source tree. Only the V8 and OpenSSL symbols are purposefully re-exported by Node.js and may be used to various extents by Addons. See Linking to Node.js’ own dependencies for additional information.
· Node.js包含了许多静态链接库,包括OpenSSL。这些类库存在于Node.js源码目录下deps/directory中。仅有v8和OpenSSL符号是有目的地再暴露,可能会被许多插件使用到。查看Node.js依赖来获得更多信息。

  以上摘录自Node.js官方文档,对插件的开发有了一个概要性的描述,其中反复提到了v8这个类库,其重要性不言而喻。事实上,我们编写的每一个Node.js的C/C++扩展都会使用到这个库。
  闲话少叙,我们开始编写第一个插件。
  1. 首先我们创建一个目录hello,在该目录下创建一个src目录用于存放我们自己编写的C/C++源码文件。
  2. src目录下hello.cc

// hello.cc#include <node.h>namespace demo {using v8::FunctionCallbackInfo;using v8::Isolate;using v8::Local;using v8::Object;using v8::String;using v8::Value;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(addon, init)}  // namespace demo

  3. 接下来,我们需要全局安装一个npm插件,node-gyp。关于node-gyp,我们只要知道是一个编译工具,可以将我们编写的C/C++扩展编译成二进制码文件,这样能够跨平台地使用咱们自行编写的插件了。(更多信息请移步node-gyp项目)
  hello目录下,我们创建一个binding.gyp(必须为这个文件名和扩展名),其中内容为:

# binding.gyp{  'targets': [    {      'target_name': 'addon',      'sources': [        'src/hello.cc'      ],      'dependencies': [      ]    }  ]}

  4. 在hello目录下Shift加鼠标右键,打开cmd控制台,执行如下命令:

node-gyp configure build

  一切顺利的话,在hello文件夹下会出现build文件夹,在build/Release下有三个名为addon的文件
  目录
  实际上我们需要用到的是后缀为.node的文件。下面写一个测试js吧。
  5. test.js内容很简单,只需要像引用其他的node模块一样require我们自己写的插件。

var addon = require('./build/Release/addon.node');console.log(addon.hello());

  执行

node test.js

  控制台显示

world

  至此,我们第一个node插件就完成了。

0 0