1. 程式人生 > >nodejs呼叫c++程式測試程式碼

nodejs呼叫c++程式測試程式碼

執行環境:

Ubuntu 12.04

node-gyp v3.3.1

Python 2.7.3 

gcc 4.6.3

make 3.81

node v0.10.37

binding.gyp(注意:不是building)

{
  "targets": [
    {
      "target_name": "add",
      "sources": [ "add.cc" ]
    }
  ]
}
add.cc
#define BUILDING_NODE_EXTENSION
#include <node.h>

using namespace v8;

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

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

  if (args.Length() < 2 || !args[0]->IsString()) {
    return ThrowException(Exception::TypeError(
      String::New("Wrong arguments")));
  }

  Local<Function> cb = Local<Function>::Cast(args[1]);
  const unsigned argc = 1;
  Local<Value> argv[argc] = {
    String::Concat(Local<String>::Cast(args[0]), String::New(" myConcat"))
  };

  cb->Call(Context::GetCurrent()->Global(), argc, argv);

  return scope.Close(Undefined());
}

Handle<Value> add(const Arguments& args) {
  HandleScope scope;
  if (args.Length() < 2 || !args[0]->IsNumber() || !args[1]->IsNumber()) {
    return ThrowException(Exception::TypeError(
      String::New("Wrong arguments")));
  }
  
  int32_t sum = args[0]->ToInteger()->Value() + args[1]->ToInteger()->Value();

  return scope.Close(Integer::New(sum));
}

void RegModule(Handle<Object> target){

  target->Set(String::NewSymbol("hello"),
      FunctionTemplate::New(hello)->GetFunction());

  target->Set(String::NewSymbol("myConcat"),
      FunctionTemplate::New(myConcat)->GetFunction());

  target->Set(String::NewSymbol("myAdd"),
      FunctionTemplate::New(add)->GetFunction());
}

//moduleName, RegisterModuleFunctionName
NODE_MODULE(add, RegModule);
test.js
var test = require('./build/Release/add');

var str = test.hello();
console.log(str);

test.myConcat('nodejs', function(data) {
  console.log(data);
});

console.log("2+3="+test.myAdd(2,3));

編譯執行:

node-gyp configure build

node test.js

結果:

hello,world
nodejs myConcat
2+3=5

注意有些版本程式碼則是這樣的:

下面程式碼則在如下環境執行成功

Ubuntu 14.04.1 LTS

node-gyp v3.3.1

Python 2.7.6

gcc 4.8.2

make 3.81

node v5.2.0

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

using namespace v8;

// 傳入了兩個引數,args[0] 字串,args[1] 回撥函式
void hello(const FunctionCallbackInfo<Value>& args) {
  // 使用 HandleScope 來管理生命週期
  Isolate* isolate = Isolate::GetCurrent();
  HandleScope scope(isolate);

  // 判斷引數格式和格式
  if (args.Length() < 2 || !args[0]->IsString()) {
    isolate->ThrowException(Exception::TypeError(
      String::NewFromUtf8(isolate, "Wrong arguments")));
    return;
  }

  // callback, 使用Cast方法來轉換
  Local<Function> callback = Local<Function>::Cast(args[1]);
  Local<Value> argv[1] = {
    // 拼接String
    String::Concat(Local<String>::Cast(args[0]), String::NewFromUtf8(isolate, " world"))
  };
  // 呼叫回撥, 引數: 當前上下文,引數個數,引數列表
  callback->Call(isolate->GetCurrentContext()->Global(), 1, argv);
}

// 相當於在 exports 物件中新增 { hello: hello }
void init(Handle<Object> exports) {
  NODE_SET_METHOD(exports, "hello", hello);
}

// 將 export 物件暴露出去
// 原型 `NODE_MODULE(module_name, Initialize)`
NODE_MODULE(test, init);

型別判斷
Local<Value> arg = args[0];
bool isArray = arg->IsArray();
bool isBoolean = arg->IsBoolean();
bool isNumber = arg->IsNumber();
bool isInt32 = arg->IsInt32();
型別轉換
Local<Value> arg = args[0];
Local<Object> = arg->ToObject();
Local<Boolean> = arg->ToBoolean();
Local<Number> = arg->ToNumber();
Local<Int32> = arg->ToInt32 ();
Local<Function> callback = Local<Function>::Cast(args)