天天看點

編寫原生的Node.js子產品

通常,我們開發原生Node.js子產品包括但不僅限于以下原因:

對性能有比較苛刻要求的應用。盡管Node.js得益于libuv,在異步I/O操作很有優勢,但遇到數字計算時并不是一個很好的選擇。

使用更加底層的API,比如作業系統層面的。

在C/C++和Node.js之間建立一個Bridge,進行通信。

Node.js Addons是動态連結的可共享對象,由C/C++編寫而成。可以在Node.js中通過require()方法進行調用,使用起來像調用Node.js普通子產品一樣。 —— 來自Node.js官方文檔

這意味着如果處理得當的話,子產品調用者使用由C/C++編寫的原生子產品的方式和由Node.js編寫的子產品一樣。想要編寫Node.js addons,你需要了解一些基本知識:

Libuv

V8

Node.js internals

推薦閱讀這些資料。

下面我以一個常見的動态規劃問題-青蛙跳台階為例子來說明如何建立一個原生的Node.js子產品。青蛙跳台階描述為:一隻青蛙一次可以跳上一級台階,也可以跳上2級台階,求該青蛙跳上n級台階的共有多少種跳法?

首先建立一個frog_jump.cc原生檔案,.cc的意思是c with class,擴充名也可以是.cpp。Google Style Guide建議使用.cc,那麼此處還是以.cc做為擴充名吧。代碼如下:

對這段代碼的解釋:

#include "node.h" 是c++裡面引入頭檔案的方式,具體源碼:node.h,C++連結時會加載這個頭檔案。頭檔案裡面引入了v8命名空間,我們可以通過v8::标志來通路v8的接口。通路所有v8的類型,都需要使用v8::标志

通過args對象來通路Node.js傳遞過來的參數,通過args也可以擷取調用相關資訊。

通過v8::Isolate*可以擷取函數作用域,可以像JS裡面一樣進行變量指派,而不用擔心垃圾回收問題,垃圾回收器會自動進行。

args.GetReturnValue()可以對函數傳回的結果進行設定。

任何原生Node.js子產品都需要調用NODE_MODULE,NODE_MODULE是一個宏,它會進行子產品注冊操作。

C++ 有豐富的内置類型來儲存數字或者字元串,但是JS隻能識别v8::裡面定義的類型。是以,将c++的變量指派給JS時,需要轉換成可以被JS識别的類型,也即是v8::定義的類型。比如v8::String、v8::Object。

一旦源代碼編寫完成,需要将它編譯成二進制的addon.node檔案,之後才能被Node.js require。為了完成編譯操作,需要在項目的根目錄建立binding.gyp檔案,裡面定義了Build的配置。binding.gyp的内容是一個JSON。

編譯環境配置:

windows: 以管理者的身份運作npm install --global --production windows-build-tools,這個會安裝所有編譯依賴的工具。

linux: 安裝python v2.7、make和GCC

osx: 安裝xcode

雖然npm内置了一個node-gyp版本,但是這個版本沒有開放給開發者進行調用。npm install的時候會調用它來進行編譯和安裝工作。是以,開發者想要調用node-gyp必須自己安裝一個全局的node-gyp版本。

運作node-gyp configure指令會生成一個跨平台的build檔案,unix環境會生成Makefile,windows環境會在build目錄裡面生成vcxproj。

運作node-gyp build指令會生成可被Node.js調動的addon.node二進制檔案。

本文轉自xsster51CTO部落格,原文連結:http://blog.51cto.com/12945177/1932206 ,如需轉載請自行聯系原作者

上一篇: 伺服器安全
下一篇: smokeping

繼續閱讀