nodejs的C++扩展学习笔记
发布于 12 年前 作者 wangfei1204 19532 次浏览 最后一次编辑是 8 年前

Nodejs的C++扩展 首先保证nodejs和v8都正确安装

一、扩展普通函数

1、编写cpphello.cpp

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

using namespace node;
using namespace v8;

static Handle<Value> foo(const Arguments& args)
{
  return String::New("Hello World");
}

extern "C" {
  static void init(Handle<Object> target)
  {
    NODE_SET_METHOD(target, "foo", foo);
  }

  NODE_MODULE(cpphello, init);
}

2、编写wscript

import Options
from os import unlink, symlink, popen
from os.path import exists

srcdir = "."
blddir = "build"
VERSION = "0.0.1"

def set_options(opt):
  opt.tool_options("compiler_cxx")

def configure(conf):
  conf.check_tool("compiler_cxx")
  conf.check_tool("node_addon")

def build(bld):
  obj = bld.new_task_gen("cxx", "shlib", "node_addon")
  obj.target = "cpphello"
  obj.source = "cpphello.cpp"
  obj.cxxflags = ["-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE"]

def shutdown():
  if Options.commands['clean']:
    if exists('cpphello.node'): unlink('cpphello.node')
  else:
    if exists('build/default/cpphello.node') and not exists('cpphello.node'):
      symlink('build/default/cpphello.node', 'cpphello.node')

3、执行命令 /usr/local/node/bin/node-waf configure build 会在当前目录生成build/Release/cpphello.node

4、编写nodejs脚本cpphello_test.js

var cpphello = require('./build/Release/cpphello');
console.log(cpphello.foo()); // hello world

5、执行命令 /usr/local/node/bin/node cpphello_test.js 即可看到输出

二、扩展C++类 1、编写point.cpp

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

#include <iostream>

using namespace v8;
using namespace node;

class Point 
:ObjectWrap
{
protected:
    int x;
    int y;
public:
    Point(int x, int y) :x(x), y(y) {
        std::cout << "point constructs" << std::endl;
    }

    ~Point() {
        std::cout << "point destructs" << std::endl;
    }

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

        // arg check is omitted for brevity
        Point *point = new Point(args[0]->Int32Value(), args[1]->Int32Value());
        point->Wrap(args.This());

        return scope.Close(args.This());
    } 

    static void Initialize(Handle<Object> target){
        HandleScope scope;

        Local<FunctionTemplate> t = FunctionTemplate::New(New);
        t->InstanceTemplate()->SetInternalFieldCount(1);

        NODE_SET_PROTOTYPE_METHOD(t, "get", Point::get);

        target->Set(String::NewSymbol("Point"), t->GetFunction());
    } 

    static Handle<Value> get(const Arguments &args){
        HandleScope scope;
        Point *p = ObjectWrap::Unwrap<Point>(args.This());
        Local<Object> result =  Object::New();
        result->Set(v8::String::New("x"), v8::Integer::New(p->x));
        result->Set(v8::String::New("y"), v8::Integer::New(p->y));
        return scope.Close(result);
    } 
};

extern "C" void init(Handle<Object> target) {
    HandleScope scope;
    Point::Initialize(target);
};

2、编写wscript

import Options
from os import unlink, symlink, popen
from os.path import exists

srcdir = "."
blddir = "build"
VERSION = "0.0.1"

def set_options(opt):
  opt.tool_options("compiler_cxx")

def configure(conf):
  conf.check_tool("compiler_cxx")
  conf.check_tool("node_addon")

def build(bld):
  obj = bld.new_task_gen("cxx", "shlib", "node_addon")
  obj.target = "point"
  obj.source = "point.cpp"
  obj.cxxflags = ["-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE"]

def shutdown():
  if Options.commands['clean']:
    if exists('point.node'): unlink('point.node')
  else:
    if exists('build/default/point.node') and not exists('point.node'):
      symlink('build/default/point.node', 'point.node')

3、执行命令 /usr/local/node/bin/node-waf configure build 会在当前目录生成build/Release/point.node

4、编写nodejs脚本testpoint.js

var pointer = require('./build/Release/point');

var p = new pointer.Point(1,2);
console.log(p.get());

var p2 = new pointer.Point(5,6);
console.log(p2.get());

5、运行查看结果 /usr/local/node/bin/node testpoint.js 输出为:

4 回复

求NAE的邀请码啊,nodejs新手亟须汲取知识见识市面,哪位大侠有邀请码就赐予我一个吧,邮箱 wangfei1204@126.com

已发送。注意查收。

谢谢letonlife,收到了 :)

回到顶部