82 lines
1.9 KiB
JavaScript
Raw Normal View History

2025-04-28 12:25:20 +08:00
'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;