Represents a loaded dynamic library.
new DynamicLibrary(path): DynamicLibrary
Loads the dynamic library without resolving any functions eagerly.
On Windows passing null is not supported.
const { DynamicLibrary, suffix } = require('node:ffi'); const lib = new DynamicLibrary(`./mylib.${suffix}`);
The path used to load the library.
An object containing previously resolved function wrappers.
An object containing previously resolved symbol addresses as bigint values.
library.close(): void
Closes the library handle.
DynamicLibrary implements the explicit resource management protocol, so a
library instance can be managed with the using declaration. Leaving the
enclosing scope invokes library.close() automatically.
import { DynamicLibrary, suffix } from 'node:ffi'; { using lib = new DynamicLibrary(`./mylib.${suffix}`); // Use `lib` here; `lib.close()` is called when the block exits. }
Calling library.close() (or disposing the library) more than once is a no-op.
After a library has been closed:
- Resolved function wrappers become invalid.
- Further symbol and function resolution throws.
- Registered callbacks are invalidated.
Closing a library does not make previously exported callback pointers safe to reuse. Node.js does not track or revoke callback pointers that have already been handed to native code.
If native code still holds a callback pointer after library.close() or after
library.unregisterCallback(pointer), invoking that pointer has undefined
behavior, is not allowed, and is dangerous: it can crash the process, produce
incorrect output, or corrupt memory. Native code must stop using callback
addresses before the library is closed or before the callback is unregistered.
Calling library.close() from one of the library's active callbacks is
unsupported and dangerous. The callback must return before the library is
closed.
library[Symbol.dispose](): void
Calls library.close(). This allows DynamicLibrary instances to be used with
the using declaration for automatic cleanup when the enclosing scope
exits. It is a no-op on a library that has already been closed.
library.getFunction(name, signature): Function
Resolves a symbol and returns a callable JavaScript wrapper.
The returned function has a .pointer property containing the native function
address as a bigint.
If the same symbol has already been resolved, requesting it again with a
different signature throws. Requesting it again with the same signature returns
the same function, as does reading it from library.functions.
const { DynamicLibrary, suffix } = require('node:ffi'); const lib = new DynamicLibrary(`./mylib.${suffix}`); const add = lib.getFunction('add_i32', { arguments: ['int32', 'int32'], return: 'int32', }); console.log(add(20, 22)); console.log(add.pointer);
library.getFunctions(definitions?): Object
When definitions is provided, resolves each named symbol and returns an
object containing callable wrappers.
When definitions is omitted, returns wrappers for all functions that have
already been resolved on the library.
library.getSymbol(name): bigint
Resolves a symbol and returns its native address as a bigint.
library.getSymbols(): Object
ObjectReturns an object containing all previously resolved symbol addresses.
library.registerCallback(signature?, callback): bigint
Creates a native callback pointer backed by a JavaScript function.
When signature is omitted, the callback uses a default void () signature.
The return value is the callback pointer address as a bigint. It can be
passed to native functions expecting a callback pointer.
const { DynamicLibrary, suffix } = require('node:ffi'); const lib = new DynamicLibrary(`./mylib.${suffix}`); const callback = lib.registerCallback( { arguments: ['int32'], return: 'int32' }, (value) => value * 2, );
Callbacks are subject to the following restrictions:
- They must be invoked on the same system thread where they were created.
- They must not throw exceptions.
- They must not return promises.
- They must return a value compatible with the declared return type.
- They must not call
library.close()on their owning library while running. - They must not unregister themselves while running.
Closing the owning library or unregistering the currently executing callback from inside the callback is unsupported and dangerous. Doing so may crash the process, produce incorrect output, or corrupt memory.
library.unregisterCallback(pointer): void
bigintReleases a callback previously created with library.registerCallback().
Calling library.unregisterCallback(pointer) for a callback that is currently
executing is unsupported and dangerous. The callback must return before it is
unregistered.
After library.unregisterCallback(pointer) returns, invoking that callback
pointer from native code has undefined behavior, is not allowed, and is
dangerous: it can crash the process, produce incorrect output, or corrupt
memory.
library.refCallback(pointer): void
bigintKeeps the callback strongly referenced by JavaScript.
Throws ERR_INVALID_ARG_VALUE if the callback function has already been
garbage collected after a previous library.unrefCallback(pointer) call, since
a collected function cannot be referenced again.
library.unrefCallback(pointer): void
bigintAllows the callback to become weakly referenced by JavaScript.
If the callback function is later garbage collected, subsequent native invocations become a no-op. Non-void return values are zero-initialized before returning to native code.
Throws ERR_INVALID_ARG_VALUE if the callback function has already been
garbage collected.