-
Notifications
You must be signed in to change notification settings - Fork 133
/
library.js
76 lines (62 loc) · 1.79 KB
/
library.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
'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 && libfile.indexOf(EXT) === -1) {
debug('appending library extension to library name', EXT);
libfile += EXT;
}
if (!lib) {
lib = {};
}
const dl = new DynamicLibrary(libfile || null, RTLD_NOW);
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: "' + libfile
+ '" 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;