82 lines
1.9 KiB
JavaScript
82 lines
1.9 KiB
JavaScript
|
'use strict';
|
||
|
/**
|
||
|
* Module dependencies.
|
||
|
*/
|
||
|
|
||
|
const DynamicLibrary = require('./dynamic_library');
|
||
|
const ForeignFunction = require('./foreign_function');
|
||
|
const VariadicForeignFunction = require('./foreign_function_var');
|
||
|
const debug = require('debug')('ffi:Library');
|
||
|
const RTLD_NOW = DynamicLibrary.FLAGS.RTLD_NOW;
|
||
|
|
||
|
/**
|
||
|
* The extension to use on libraries.
|
||
|
* i.e. libm -> libm.so on linux
|
||
|
*/
|
||
|
|
||
|
const EXT = Library.EXT = {
|
||
|
'linux': '.so',
|
||
|
'linux2': '.so',
|
||
|
'sunos': '.so',
|
||
|
'solaris':'.so',
|
||
|
'freebsd':'.so',
|
||
|
'openbsd':'.so',
|
||
|
'darwin': '.dylib',
|
||
|
'mac': '.dylib',
|
||
|
'win32': '.dll'
|
||
|
}[process.platform];
|
||
|
|
||
|
/**
|
||
|
* Provides a friendly abstraction/API on-top of DynamicLibrary and
|
||
|
* ForeignFunction.
|
||
|
*/
|
||
|
|
||
|
function Library (libfile, funcs, lib) {
|
||
|
debug('creating Library object for', libfile);
|
||
|
|
||
|
if (libfile && typeof libfile === 'string' && libfile.indexOf(EXT) === -1) {
|
||
|
debug('appending library extension to library name', EXT);
|
||
|
libfile += EXT;
|
||
|
}
|
||
|
|
||
|
if (!lib) {
|
||
|
lib = {};
|
||
|
}
|
||
|
let dl;
|
||
|
if (typeof libfile === 'string' || !libfile) {
|
||
|
dl = new DynamicLibrary(libfile || null, RTLD_NOW);
|
||
|
} else {
|
||
|
dl = libfile;
|
||
|
}
|
||
|
|
||
|
Object.keys(funcs || {}).forEach(function (func) {
|
||
|
debug('defining function', func);
|
||
|
|
||
|
const fptr = dl.get(func);
|
||
|
const info = funcs[func];
|
||
|
|
||
|
if (fptr.isNull()) {
|
||
|
throw new Error('Library: "' + dl.path()
|
||
|
+ '" returned NULL function pointer for "' + func + '"');
|
||
|
}
|
||
|
|
||
|
const resultType = info[0];
|
||
|
const paramTypes = info[1];
|
||
|
const fopts = info[2];
|
||
|
const abi = fopts && fopts.abi;
|
||
|
const async = fopts && fopts.async;
|
||
|
const varargs = fopts && fopts.varargs;
|
||
|
|
||
|
if (varargs) {
|
||
|
lib[func] = VariadicForeignFunction(fptr, resultType, paramTypes, abi);
|
||
|
} else {
|
||
|
const ff = ForeignFunction(fptr, resultType, paramTypes, abi);
|
||
|
lib[func] = async ? ff.async : ff;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return lib;
|
||
|
}
|
||
|
|
||
|
module.exports = Library;
|