C setup
Native interface for Apple platforms and Android
Slab's C interface: one header (slab.h) and one library (libslab.dylib
on macOS, libslab.so in the Android AAR, Slab.xcframework on iOS). Every
other language binding (Swift, Kotlin, Python, Dart, JavaScript) calls these
same functions.
Examples: classify, faces, tensors, chat.
Build
clang app.c -I<release>/macos -L<release>/macos -lslab -Wl,-rpath,<release>/macos -o app
Conventions
- Handles. Every object is an opaque
uint8_t *from a_newfunction, released with its_freefunction. No structs cross the interface. - Results. Functions returning
int32_treturn 1 on success and 0 on failure. Exceptions: counts and indexes, andslab_session_next(1 = text ready, 0 = finished, -1 = error). - Errors. After a failure, ask the object that failed:
slab_session_error_code/_message_ptr/_message_len(same for Frame), andslab_config_runtime_license_error*for license problems. - Strings in. Always
(pointer, length)in UTF-8 bytes; no NUL needed. - Strings out. A
_ptrfunction and a_lenfunction; print with"%.*s". Valid until that object's next mutating call or its free. - Output memory. Pointers from an Output stay valid until the next run, start or next into that Output, or until it is freed, even if the session is freed first.
- Borrowed input.
copy = 0on tensor and pixel setters means Slab reads your buffer only duringslab_session_run/slab_session_start; you may free it once they return.copy = 1copies it immediately. - Threads. One operation at a time per session (a second one gets
SLAB_ERR_BUSY); separate sessions run in parallel. Loaded Frames can be shared across threads. Give each thread its own Input and Output.slab_session_cancelworks from any thread.
The flow
slab_config_new, set the models folder and cache folder, and attach the runtime license withslab_config_set_runtime_license. On Android, callslab_runtime_bind_android(env, application_context)once first; it returns 0 on success.slab_session_new(cfg)per model, optional settings, thenslab_session_open. The session copies the config's settings and license.- Fill an Input (
slab_input_set_frame,slab_input_set_f32, a prompt...), callslab_session_run, read the Output. - Free everything with the
_freefunctions, in any order.
Functions
Library
| Function | Description |
|---|---|
slab_version() |
Version string (NUL-terminated) |
slab_probe_backend(cfg, backend) |
1 if this device has the backend |
slab_runtime_bind_android(env, context) |
Android: bind to the app once; 0 on success |
Config
| Function | Description |
|---|---|
slab_config_new(), slab_config_free(cfg) |
Create / free |
slab_config_set_models_dir(cfg, path, len) |
Folder for relative model paths |
slab_config_set_cache_dir(cfg, path, len) |
Writable folder for prepared-model caches |
slab_config_set_skel_dir(cfg, path, len) |
Android Hexagon NPU: writable folder with the QNN skel libraries |
slab_config_set_backend(cfg, backend) |
Default backend for new sessions |
slab_config_set_threads(cfg, n) |
CPU worker threads |
slab_config_set_verify_weights(cfg, on) |
Hash-check all weights on open |
slab_config_set_runtime_license(cfg, text, len) |
Verify and attach the license string; on failure the previous license stays |
slab_config_set_runtime_license_bytes(cfg, bytes, len) |
Same, 640-byte binary form |
slab_config_clear_runtime_license(cfg) |
Detach the license |
slab_config_runtime_license_status(cfg) |
0 OK, 1 missing, 10 not yet valid, 11 expired, 15 clock unavailable |
slab_config_runtime_license_error(cfg) |
Reason the last license call failed (codes below) |
slab_config_runtime_license_error_message_ptr/_len(cfg) |
Same, as text |
slab_config_runtime_license_expires_at(cfg) |
Expiry, Unix seconds |
slab_config_runtime_license_integrator_id_ptr/_len(cfg) |
Licensed integrator ID (hex) |
slab_config_runtime_license_client_id_ptr/_len(cfg) |
Licensed client ID (hex) |
slab_config_set_unlock_key(cfg, key32, key_id) |
Protected models: install the 32-byte key |
slab_config_set_unlock_key_hex(cfg, hex, len, key_id) |
Same, 64 hex characters |
slab_config_set_issuer_public_key(cfg, pubkey65, app_id) |
Protected models: trust a model-token issuer |
slab_config_set_license_token(cfg, token, len) |
Protected models: unlock with a model token |
slab_config_clear_unlock_key(cfg) |
Remove the installed key (keys are process-wide) |
License reason codes: 0 OK, 1 missing, 2 format, 3 issuer, 4 signature, 5 platform, 6 identity unavailable, 7 wrong app, 8 release, 9 feature, 10 not yet valid, 11 expired, 12 memory, 13 invalid argument, 14 busy, 15 clock unavailable.
Frame
| Function | Description |
|---|---|
slab_frame_new(), slab_frame_free(f) |
Create / free |
slab_frame_load_file(f, path, len) |
Decode a JPEG or PNG file |
slab_frame_load_encoded(f, bytes, len) |
Decode JPEG or PNG bytes |
slab_frame_set_pixels(f, data, length, width, height, stride, format, orientation, copy) |
Raw pixels (e.g. a camera frame). stride 0 = packed; orientation EXIF 1–8 |
slab_frame_crop_into(src, dst, x, y, w, h) |
Make dst a view of a region (no copy); keep src alive |
slab_frame_width/height/format/stride/data_ptr(f) |
Image properties |
slab_frame_error_code(f), slab_frame_error_message_ptr/_len(f) |
Last error |
Session
| Function | Description |
|---|---|
slab_session_new(cfg), slab_session_free(s) |
Create / free |
slab_session_inspect(s, path, len), slab_session_inspect_fd(s, fd, offset, length) |
Read the model's description without weights |
slab_session_check_backend(s, backend) |
Dry run: 1 if the backend can run it, else 0 with the reason in the error message |
slab_session_estimated_memory_bytes(s) |
Memory the model needs |
slab_session_open(s, path, len), slab_session_open_fd(s, fd, offset, length) |
Load and prepare the model |
slab_session_unload(s), slab_session_reload(s) |
Free / reload the weights, keeping the session |
slab_session_set_backend(s, backend) |
Before open: request a backend (AUTO: model preference, else NPU → GPU → CPU) |
slab_session_set_warmup(s, on) |
Before open: run once during open |
slab_session_set_batch_size(s, n) |
Before open: images per run |
slab_session_set_context_length(s, n) |
Generative: conversation size in tokens |
slab_session_set_activation_fp16(s, on) |
Generative: 16-bit activations |
slab_session_set_resize_mode(s, mode) |
SLAB_RESIZE_STRETCH, _LETTERBOX, _CENTER_CROP (overrides the model file) |
slab_session_set_letterbox_pad(s, byte) |
Letterbox padding (default 114) |
slab_session_set_color_bgr(s, on) |
Feed BGR instead of RGB |
slab_session_set_normalization(s, scale, m0, m1, m2, s0, s1, s2) |
(pixel * scale - mean) / std per channel |
slab_session_run(s, in, out) |
Run once (generative: the whole answer) |
slab_session_start(s, in, out), slab_session_next(s, out) |
Generative streaming: start, then next until it returns 0 |
slab_session_cancel(s) |
Stop the current run or generation; any thread |
slab_session_reset(s) |
Generative: forget the conversation |
slab_session_requested_backend/active_backend(s) |
Requested / actual backend |
slab_session_is_protected/is_generative(s) |
Model kind |
slab_session_input_count/output_count(s) |
Tensor counts |
slab_session_input_name_ptr/_len(s, i), ..._dtype, ..._rank, ..._dim(s, i, axis), ..._bytes |
Input tensor description (same for output) |
slab_session_label_count(s), slab_session_label_ptr/_len(s, i) |
Class labels from the model file |
slab_session_has_meta(s, key, len), slab_session_meta_str_ptr/_len, _meta_i64, _meta_f64 |
Read model-file settings |
slab_session_set_runtime_license(s, text, len) (and _bytes) |
Renew a live session's license without reloading |
slab_session_runtime_license_status/error/error_message_ptr/_len/expires_at(s) |
As on Config |
slab_session_error_code(s), slab_session_error_message_ptr/_len(s) |
Last error |
Input
| Function | Description |
|---|---|
slab_input_new(), slab_input_free(in), slab_input_clear(in) |
Create / free / empty |
slab_input_set_frame(in, f), slab_input_set_named_frame(in, name, len, f) |
Image for the first or a named input |
slab_input_add_batch_frame(in, f) |
Add an image to a batch (up to 64) |
slab_input_set_f32(in, idx, data, count, copy), slab_input_set_named_f32(in, name, len, data, count, copy) |
Float tensor |
_i64, _f16 (uint16_t binary16), _u8 variants |
Other tensor types |
slab_input_set_prompt(in, text, len) |
Single user message |
slab_input_add_message(in, role, role_len, text, text_len) |
Add a system / user / assistant message (up to 16) |
slab_input_add_image_message(in, role, role_len, frame, text, text_len) |
Message with an image |
slab_input_set_image_tiled(in, on, longest_edge) |
Split large images into tiles (512–2048) |
slab_input_set_max_tokens/temperature/top_p/top_k/min_p/repeat_penalty/seed(in, v) |
Sampling |
slab_input_add_stop(in, text, len) |
Stop text |
slab_input_set_json_schema(in, schema, len) |
Constrain the answer to JSON |
slab_input_set_amount_decimals(in, n) |
Constrain the answer to a decimal amount (1–9; 0 off) |
Output
| Function | Description |
|---|---|
slab_output_new(), slab_output_free(out) |
Create / free |
slab_output_latency_ms(out), slab_output_backend_used(out) |
Timing and backend of the last run |
slab_output_tensor_count(out), slab_output_index_of(out, name, len) |
Tensors |
slab_output_dtype/rank/dim(out, i[, axis]), slab_output_elem_count(out, i) |
Tensor description |
slab_output_f32_ptr/_len(out, i), slab_output_copy_f32(out, i, dst, max) |
Float data |
slab_output_i64_ptr, slab_output_copy_i64, slab_output_f16_ptr, slab_output_u8_ptr |
Other types |
slab_output_compute_top_k(out, tensor, k, softmax) |
Rank classes; then slab_output_top_class_id/top_score/top_label_ptr/_len(out, rank) |
slab_output_decode_boxes(out, score, iou, max) |
Decode detections (−1 if not a detection model); then slab_output_box_x1/y1/x2/y2/score/class_id/label_ptr/_len(out, i) |
slab_output_box_landmark_count(out, i), slab_output_box_landmark_x/y(out, i, p) |
Keypoints, in original image pixels |
slab_output_scale_x/scale_y/pad_x/pad_y(out) |
How the image was fitted |
slab_output_normalize_l2(out, i), slab_output_cosine_similarity(a, i, b, j) |
Embeddings |
slab_output_to_frame(out, i, scale, offset, dst) |
Image-shaped tensor to a Frame |
slab_output_text_ptr/_len(out), slab_output_full_text_ptr/_len(out) |
New text / whole answer |
slab_output_finish_reason/prompt_tokens/cached_prompt_tokens/generated_tokens(out) |
Generation details |
Constants
SLAB_BACKEND_AUTO/CPU/GPU/NPU (0–3), SLAB_DTYPE_F16/F32/I64/U8 (1, 2,
3, 5), SLAB_PIXEL_RGB8/BGR8/RGBA8/BGRA8/GRAY8 (1–5),
SLAB_RESIZE_STRETCH/LETTERBOX/CENTER_CROP (0–2),
SLAB_FINISH_NONE/EOS/STOP/LENGTH/CANCELLED (0–4), and error codes
SLAB_ERR_OK 0 … SLAB_ERR_RUNTIME_LICENSE 16 (see slab.h).