ffi-tools

Experimental hacky tools and wrappers for easing node-ffi usage and generating bindings.

npm install ffi-tools
4 downloads in the last month

node ffi-tools

Some hacky experiments with the newly updated node-ffi that works cross-platform.

Usage

Define Interfaces

Super abbreviated and automated handling of node-ffi function definitions.

function _int(s){ return function(n){ return ['int'+s, n] } }
function _uint(s){ return function(n){ return ['uint'+s, n] } }
var uint16 = _uint(16);
var uint32 = _uint(32);
var HANDLE = 'pointer';
var DWORD = 'uint32';

var FILETIME = Struct('FILETIME',
  [ uint32('low'),
    uint32('high') ]);

var SYSTEMTIME = Struct('SYSTEMTIME',
  [ uint16('year'),
    uint16('month'),
    uint16('dayOfWeek'),
    uint16('day'),
    uint16('hour'),
    uint16('minute'),
    uint16('second'),
    uint16('millisecond') ]);

var kernel32 = new Library('kernel32', {
  GetFileTime: {
    _ret_: 'uint8',
    fileHandle: HANDLE,
    _out_creationTime: FILETIME,
    _out_accessTime: FILETIME,
    _out_writeTime: FILETIME
  },
  GetSystemTime: {
    _out_: SYSTEMTIME
  },
  GetShortPathNameA: {
    _ret_: DWORD,
    longPath: 'string',
    _out_: 'string',
    _buffer: [DWORD, 256]
  }
});

Created Interfaces

kernal32.GetFileTime = [Function: GetFileTime(fileHandle)];
//-->
  { creationTime: { high: Number, low: Number },
    accessTime: { high: Number, low: Number },
    writeTime: { high: Number, low: Number },
    ret: Boolean(success) }

kernel32.GetSystemTime = [Function: GetSystemTime];
//-->
  { year: Number,
    month: Number,
    dayOfWeek: Number,
    day: Number,
    hour: Number,
    minute: Number,
    second: Number,
    millisecond: Number }

kernel32.GetShortPathNameA = [Function: GetShortPathNameA(longPath)];
//-->
  String(shortPath) //'C:\\Programs Files (x86)\\nodejs' - > 'C:\\PROGRA~2\\nodejs'

Interface toString to produce fixed source code bindings

kernel32.toString() produces the following fully standalone and functional code:

var ffi = require('node-ffi');

var kernel32 = { _lib: new ffi.DynamicLibrary('kernel32.dll', 2) };

var FILETIME = ffi.Struct(
  ['uint32', 'low'],
  ['uint32', 'high']
);

var SYSTEMTIME = ffi.Struct(
  ['uint16', 'year'],
  ['uint16', 'month'],
  ['uint16', 'dayOfWeek'],
  ['uint16', 'day'],
  ['uint16', 'hour'],
  ['uint16', 'minute'],
  ['uint16', 'second'],
  ['uint16', 'millisecond']
);

kernel32.GetFileTime = function(){
  var ff = new ffi.ForeignFunction(kernel32._lib.get('GetFileTime'), 'uint8', ['pointer','pointer','pointer','pointer'], false);
  return function GetFileTime(fileHandle){
    var out = Object.create(null);
    out.creationTime = new FILETIME;
    out.accessTime = new FILETIME;
    out.writeTime = new FILETIME;
    out.ret = ff(fileHandle, out.creationTime.pointer, out.accessTime.pointer, out.writeTime.pointer);
    return out;
  }
}();

kernel32.GetSystemTime = function(){
  var ff = new ffi.ForeignFunction(kernel32._lib.get('GetSystemTime'), 'void', ['pointer'], false);
  return function GetSystemTime(){
    var out = new SYSTEMTIME;
    ff(out.pointer);
    return out;
  }
}();

kernel32.GetShortPathNameA = function(){
  var ff = new ffi.ForeignFunction(kernel32._lib.get('GetShortPathNameA'), 'void', ['string','pointer','uint32'], false);
  return function GetShortPathNameA(longPath){
    var out = new ffi.Pointer(4);
    ff(longPath, out, 256);
    out = out.getCString();
    return out;
  }
}();
npm loves you