Hatena::Groupnodejs

Node.jsで遊ぶよ

 | 

2010-12-12

C++ で node.js ライブラリを作る・その1

03:19

非同期の説明の前にまず同期ライブラリを書いてみる。

node::ObjectWrap というのが、JavaScriptオブジェクトの内部に任意の C のオブジェクトポインター)を持たせるための仕組みで、それを継承すると簡単。

  • file.cc
#include <node.h>
#include <stdio.h>

using namespace v8;
using namespace node;

class File : ObjectWrap {
  public:
    static void
    Initialize (const Handle<Object> target) {
      HandleScope scope;
      Local<FunctionTemplate> tmpl = FunctionTemplate::New(New);
      tmpl->InstanceTemplate()->SetInternalFieldCount(1);
      NODE_SET_PROTOTYPE_METHOD(tmpl, "write", Write);

      target->Set(String::New("File"), tmpl->GetFunction());
    }

    ~File () {
      fclose(fp);
    }
  private:
    FILE *fp;

    File (const char *filename) {
      if ((fp = fopen(filename, "w")) == NULL) {
        throw "file_open_error";
      }
    }

    static Handle<Value>
    New (const Arguments& args) {
      HandleScope scope;
      if (!args.IsConstructCall()) return args.Callee()->NewInstance();
      try {
        (new File(*String::Utf8Value(args[0])))->Wrap(args.This());
      } catch (const char *msg) {
        return ThrowException(Exception::Error(String::New(msg)));
      }
      return args.This();
    }

    int Write (const char *str) {
      return fprintf(fp, "%s\n", str);
    }

    static Handle<Value>
    Write (const Arguments& args) {
      HandleScope scope;
      Unwrap<File>(args.This())->Write(*String::Utf8Value(args[0]));
      return Undefined();
    }
};

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

それと同じディレクトリに wscript というファイルを作って、こんなふうに書いて、

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.source = "file.cc"
  obj.target = "file"

node-waf configure && node-waf すると、build というディレクトリができて、その中に build/default/file.node というファイルができる。

node.js からはこんなふうに使える。

var File = require('./build/default/file').File;
var file = new File("foo.txt");
file.write("foo");

ポイントは、

など。

ゲスト



トラックバック - http://nodejs.g.hatena.ne.jp/edvakf/20101212
 |