0.4.6 • Published 4 years ago
ffi-adapter v0.4.6
ffi-adapter

Image suorce: Rainbow Colors Electronic
Foreign Function Interface Adapter Powered by Decorator & TypeScript
Features
- Binding shared library(
.dll/.so/.dylib) to a TypeScript class by decorators. - Support
asyncmode when a class method defined with a return type ofPromise. - Supports Windows(
.dll), Linux(.so), and MacOS(.dylib). - The class will be forced singleton.
Requirement
- Node.js v10 or v11 for ffi (neither v12 nor v13, see #554)
- TypeScript with
--target ES5,--experimentalDecorators, and--emitDecoratorMetadataoptions on.
Example
Background:
- We have a shared library file
libfactorial.so(.dll/.dylibas well) - the library has a function
uint64_t factorial(int) - We want to use
factorial()in TypeScript.
Talk is cheap, show me the code
import {
LIBRARY,
API,
RETURN,
} from 'ffi-adapter'
@LIBRARY('./libfactorial')
export class LibFactorial {
@API() factorial (n: number): number { return RETURN(n) }
}
const lib = new LibFactorial()
console.log('factorial(5) =', lib.factorial(5))
// Output: factorial(5) = 120That's it! Use it is that easy!
Reference
import {
LIBRARY,
API,
RETURN,
} from 'ffi-adapter'All you need is the above two decorators and one function:
LIBRARY(libraryFile: string)- Class decoratorAPI(returnType?: FfiReturnType)- Method decoratorRETURN(...args: any[])- Method need to return this function to confirm the adapting.
1 LIBRARY(libraryFile: string)
libraryFile:string- The shared library file path, which will be adapted and binding to the class.
@LIBRARY('./libfactorial')
class LibFactorial { /* ... */ }2 API(returnType?: FfiReturnType)
returnType:FfiReturnType- Optional. Specify the library function return type. Can be refered automatically by the TypeScript if the method return is not aPromise.
Specific the library function return type, and bind the same name function from library to the decorated class method.
@API('uint64') factorial(n: number): Promise<number> { ... }3 RETURN(...args: any[]): any
args:any[]- The method args. Just place every args of the method, to th RETURN function.
@API() factorial(...args: any[]) { return RETURN(...args) }The actual return value will be take care by the @API decorator.
Tutorial
Credit: https://github.com/node-ffi/node-ffi/tree/master/example/factorial
1 For the belowing C source code: factorial.c
#include <stdint.h>
#if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
EXPORT uint64_t factorial(int max) {
int i = max;
uint64_t result = 1;
while (i >= 2) {
result *= i--;
}
return result;
}2 We can build a shared library libfactorial based on it
2.1 To compile libfactorial.dylib on OS X
gcc -dynamiclib -undefined suppress -flat_namespace factorial.c -o libfactorial.dylib2.2 To compile libfactorial.so on Linux/Solaris/etc
gcc -shared -fpic factorial.c -o libfactorial.so2.3 To compile libfactorial.dll on Windows (http://stackoverflow.com/a/2220213)
cl.exe /D_USRDLL /D_WINDLL factorial.c /link /DLL /OUT:libfactorial.dll3 We can adapte the shared library into TypeScript as a Class
Save the following code to file lib-factorial.ts:
import {
LIBRARY,
API,
RETURN,
} from 'ffi-adapter'
@LIBRARY('./libfactorial')
export class LibFactorial {
@API() factorial (n: number): number { return RETURN(n) }
}4 Let's use it
import { LibFactorial } from './lib-factorial.ts'
const lib = new LibFactorial()
console.log('factorial(5) =', lib.factorial(5))
// Output: factorial(5) = 120You will agree with me that it's super clean, beautiful, and easy to maintain! ;-)
Similiar Projects
Resources
- TypeScript - Class Decorators
- Generate ffi bindings from header files
- node-ffi使用指南
- Node FFI Tutorial
- Use the Microsoft C++ toolset from the command line - To open a developer command prompt window
- FFI Definitions of Windows win32 api for node-ffi-napi
- Decorators & metadata reflection in TypeScript: From Novice to Expert - PART IV: Types serialization & The metadata reflection API
- decorator metadata is emitted only on decorated members
Knowned Issues
History
master
v0.4 (Aug 6, 2021)
Support all Node.js versions (10/11/12/13/14/15/16) now!
v0.2 (Feb 4, 2020)
The first version.
- Use
@LIBRARY(),@API(), andRETURN()as decorators to bind a shared library to a TypeScript Class.
Author
Copyright & License
- Code & Docs © 2020-now Huan LI \zixia@zixia.net\
- Code released under the Apache-2.0 License
- Docs released under Creative Commons
