Library functions#

Loading libraries#

To declare functions, start by loading the shared library with koffi.load(filename).

1const koffi = require('koffi');
2const lib = koffi.load('/path/to/shared/library'); // File extension depends on platforms: .so, .dll, .dylib, etc.

This library will be automatically unloaded once all references to it (including all the functions that use it, as described below).

Starting with Koffi 2.3.20, you can explicitly unload a library by calling lib.unload(). Any attempt to find or call a function from this library after unloading it will crash.


On some platforms (such as with the musl C library on Linux), shared libraries cannot be unloaded, so the library will remain loaded and memory mapped after the call to lib.unload().

Function definitions#

Definition syntax#

Use the object returned by koffi.load() to load C functions from the library. To do so, you can use two syntaxes:

  • The classic syntax, inspired by node-ffi

  • C-like prototypes

Classic syntax#

To declare a function, you need to specify its non-mangled name, its return type, and its parameters. Use an ellipsis as the last parameter for variadic functions.

1const printf = lib.func('printf', 'int', ['str', '...']);
2const atoi = lib.func('atoi', 'int', ['str']);

Koffi automatically tries mangled names for non-standard x86 calling conventions. See the section on calling conventions for more information on this subject.

C-like prototypes#

If you prefer, you can declare functions using simple C-like prototype strings, as shown below:

1const printf = lib.func('int printf(const char *fmt, ...)');
2const atoi = lib.func('int atoi(str)'); // The parameter name is not used by Koffi, and optional

You can use () or (void) for functions that take no argument.

Variadic functions#

Variadic functions are declared with an ellipsis as the last argument.

In order to call a variadic function, you must provide two Javascript arguments for each additional C parameter, the first one is the expected type and the second one is the value.

1const printf = lib.func('printf', 'int', ['str', '...']);
3// The variadic arguments are: 6 (int), 8.5 (double), 'THE END' (const char *)
4printf('Integer %d, double %g, str %s', 'int', 6, 'double', 8.5, 'str', 'THE END');

On x86 platforms, only the Cdecl convention can be used for variadic functions.

Calling conventions#

By default, calling a C function happens synchronously.

Most architectures only support one procedure call standard per process. The 32-bit x86 platform is an exception to this, and Koffi supports several x86 conventions:


Classic form

Prototype form



koffi.cdecl or koffi.func


This is the default convention, and the only one on other platforms




This convention is used extensively within the Win32 API




Rarely used, uses ECX and EDX for first two parameters




Rarely used, uses ECX for first parameter

You can safely use these on non-x86 platforms, they are simply ignored.

Below you can find a small example showing how to use a non-default calling convention, with the two syntaxes:

1const koffi = require('koffi');
2const lib = koffi.load('user32.dll');
4// The following two declarations are equivalent, and use stdcall on x86 (and the default ABI on other platforms)
5const MessageBoxA_1 = lib.stdcall('MessageBoxA', 'int', ['void *', 'str', 'str', 'uint']);
6const MessageBoxA_2 = lib.func('int __stdcall MessageBoxA(void *hwnd, str text, str caption, uint type)');