用C++為nodejs 寫組件,提高node處理效率


  昨天研究了下如何用C++和node交互,在node的程序中,如果有大數據量的計算,處理起來比較慢,可以用C++來處理,然后通過回調(callback的形式),返回給node。

首先,先來看看node 是如何和C++交互吧。

前提:需要安裝nodejs 環境,安裝node-gyp 包。采用npm 方式安裝,這個太方便了,修改本文件夾下面的package.json 依賴選項,然后執行npm install 就可以了。

1.以hello world 為例來說明:

1)建立一個文件夾hello,在這個文件夾里依次添加3個文件,hello.cc, binding.gyp,test.js (其中hello.cc 是c++的源程序文件,binding.gyp 是編譯模塊的配置文件,這個文件被

node-gyp程序編譯,test.js是nodejs的調用程序。)

文件下結構如下:

hello.cc 代碼如下:

#include <node.h>
#include <v8.h>

using namespace v8;

Handle<Value> Method(const Arguments& args) {
  HandleScope scope;
  return scope.Close(String::New("hello,world"));
}

void init(Handle<Object> exports) {
  exports->Set(String::NewSymbol("hello"),
      FunctionTemplate::New(Method)->GetFunction());
}

NODE_MODULE(hello, init)

binding.gyp如下:

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

test.js 為:

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

console.log(addon.hello()); 

2) 直接執行 node-gyp configure build  就直接編譯了。

3) 運行 node test.js 就輸出結果。

好了,就這么簡單。node就可以直接調用C++編寫的程序。

對上面程序的解釋:在hello.cc 中,我們首先創建了一個函數Method, 此函數返回一個"hello,world"的字符串,后面我們又創建了一個init的函數,作為一個初始化函數,我們去調用了一個函數

最后面,我們將這個模塊綁定為:NODE_MODULE(hello, init)

在官網中指出,所有的node的插件必須輸出一個初始化的函數,也就是說如下代碼是在每個模塊都必須有的,固定格式。

void Initialize (Handle<Object> exports);
NODE_MODULE(module_name, Initialize)

其中 module_name 必須對應上binding.gyp中的 target_name 就可以了。

經過了node-gyp configure build 編譯以后會在當前文件下生成一個build 的新的文件夾。我們通過在test.js中去引用這個build的結果,就可以調用C++的寫的程序了。

OK,一個簡單的node與C++程序就寫完了。

現在這樣node就可以和C++寫的程序交互了,直接去調用C++寫的程序了。如果覺得node處理不過來,都可以通過C++來處理。

2.node 通過callback 回調的方式,調用C++處理后的結果返回給node

1)按照上面的方式,首先建立3個文件 callback.cc, binding.gyp,test.js

callback.cc:

#define BUILDING_NODE_EXTENSION
#include <node.h>

using namespace v8;

Handle<Value> RunCallback(const Arguments& args) {
  HandleScope scope;

  Local<Function> cb = Local<Function>::Cast(args[0]);
  const unsigned argc = 1;
  Local<Value> argv[argc] = { Local<Value>::New(String::New("hello world")) };
  cb->Call(Context::GetCurrent()->Global(), argc, argv);

  return scope.Close(Undefined());
}

void Init(Handle<Object> exports, Handle<Object> module) {
  module->Set(String::NewSymbol("exports"),
      FunctionTemplate::New(RunCallback)->GetFunction());
}

NODE_MODULE(callback, Init)

binding.gyp:

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

test.js:

var addon = require('./build/Release/callback');

addon(function(msg){
  console.log(msg); // 'hello world'
});

2)編譯,在終端輸入:node-gyp configure build ,會在當前目錄下生成一個build 的新文件下

3)測試,node test.js  輸出 //hello world

注意:如果有多個.cc 的文件,一定要將他們都包含在binding.gyp中,不然編譯是通過了,但是node調用會報錯。

測試代碼地址:https://github.com/yupeng528/node-addon-test

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM