Xiaopei's DokuWiki

These are the good times in your life,
so put on a smile and it'll be alright

User Tools

Site Tools


it:nodejs:c-addon

Node.js Addon

写 Addon

  1. 写 c
    // hello.cc
    #include <node.h>
     
    namespace demo {
     
    using v8::FunctionCallbackInfo;
    using v8::HandleScope;
    using v8::Isolate;
    using v8::Local;
    using v8::Object;
    using v8::String;
    using v8::Value;
     
    void Method(const FunctionCallbackInfo<Value>& args) {
      Isolate* isolate = args.GetIsolate();
      args.GetReturnValue().Set(String::NewFromUtf8(isolate, "world"));
    }
     
    void init(Local<Object> exports) {
      NODE_SET_METHOD(exports, "hello", Method);
    }
     
    NODE_MODULE(addon, init)
     
    }  // namespace demo
  2. 写 binding.gyp
    {
      "targets": [
        {
          "target_name": "addon",
          "sources": [ "hello.cc" ]
        }
      ]
    }
  3. 构建
    $ ls 
    binding.gyp hello.cc
     
    $ node-gyp configure
    $ node-gyp build
     
    $ ls
    binding.gyp build hello.cc
  4. 使用
    // hello.js
    var addon = require('./build/Release/addon');
     
    console.log(addon.hello()); // 'world'

不写 Addon,直接在 js 中使用 dynamic libraries(.dll/.so)

简单的 ffi 用法

其中 double 等都是 ref.types 的别名,如 string 即为 ref.types.CString

var ffi = require('ffi');
 
var libm = ffi.Library('libm', {
  'ceil': [ 'double', [ 'double' ] ]
});
console.log(libm.ceil(1.5)); // 2
 
// You can also access just functions in the current process by passing a null
var current = ffi.Library(null, {
  'atoi': [ 'int', [ 'string' ] ]
});
console.log(current.atoi('1234')); // 1234

使用 ref

涉及到的 sqlite 文档见:List Of SQLite Functions

var libsqlite3 = ffi.Library('libsqlite3', {
  /* 
  int sqlite3_open(
    const char *filename,   // Database filename (UTF-8) 
    sqlite3 **ppDb          // OUT: SQLite db handle 
  );
  */
  'sqlite3_open': [ 'int', [ 'string', sqlite3PtrPtr ] ],
  /*
  int sqlite3_close(sqlite3*);
  */
  'sqlite3_close': [ 'int', [ sqlite3PtrPtr ] ],
  /*
  int sqlite3_exec(
    sqlite3*,                                  // An open database 
    const char *sql,                           // SQL to be evaluated 
    int (*callback)(void*,int,char**,char**),  // Callback function 
    void *,                                    // 1st argument to callback 
    char **errmsg                              // Error msg written here 
  );
  */
  'sqlite3_exec': [ 'int', [ sqlite3PtrPtr, 'string', 'pointer', 'pointer', stringPtr ] ],
  /*
  int sqlite3_changes(sqlite3*);
  */
  'sqlite3_changes': [ 'int', [ sqlite3PtrPtr ]]
});
 
// now use them:
var dbPtrPtr = ref.alloc(sqlite3PtrPtr);
libsqlite3.sqlite3_open("test.sqlite3", dbPtrPtr);
var dbHandle = dbPtrPtr.deref();

参数中的 char *

用 c 测试 .so

it/nodejs/c-addon.txt · Last modified: 2015/09/17 16:48 by admin