Skip to main content
JSCallback wraps a TypeScript function so it can be passed to C code that expects a function pointer.

Example

import { JSCallback, FFIType } from 'arkffi';

const cb = new JSCallback(
  (a: number, b: number): number => a + b,
  { args: [FFIType.int32, FFIType.int32], returns: FFIType.int32 },
);

cb.call(2, 3); // → 5
cb.ptr;        // → slot handle or trampoline address
cb.close();

Constructor

constructor(
  callback: (...args: any[]) => any,
  def: {
    args: string[];
    returns: string;
    threadsafe?: boolean;
  },
);
ParameterTypeDefaultDescription
callbackFunctionTypeScript function to wrap
def.argsstring[]C function argument type codes
def.returnsstringC function return type code
def.threadsafebooleanfalseSafe to call from any thread

Properties

ptr

get ptr(): number;
Returns a function pointer that can be passed to native C code.
  • Non-threadsafe: returns a slot handle (small integer).
  • Threadsafe: returns a real executable trampoline address.

getHandle()

getHandle(): number;
Returns the internal slot handle, used for ffi.invokeCallback() and ffi.callCallbackThreadSafe().

threadsafe

readonly threadsafe: boolean;
Whether the callback was created with thread-safe mode.

Methods

call()

call(...args: any[]): any;
Invokes the TypeScript callback.
cb.call(7);  // → 70

close()

close(): void;
Releases the callback resources.
cb.close();
cb.call(1); // throws

Thread-Safe Callbacks

const cb = new JSCallback(fn, {
  args: [FFIType.int32],
  returns: FFIType.double,
  threadsafe: true,
});
cb.threadsafe; // → true
When threadsafe: true, cb.ptr returns a real C function pointer (trampoline) that can be passed directly to native C functions:
const fn = CFunction({ args: [FFIType.int32], returns: FFIType.int32, ptr: cb.ptr });
fn(7); // → 21
fn.close();

Closure Capture

let factor = 10;
const cb = new JSCallback(
  (x: number): number => x * factor,
  { args: [FFIType.int32], returns: FFIType.int32 },
);
cb.call(5); // → 50
factor = 20;
cb.call(5); // → 100
cb.close();