C SDK API Reference

May 2, 2026 · View on GitHub

Complete API reference for the BoxLite C SDK.

Overview

The C SDK provides C-compatible FFI bindings for integrating BoxLite into C/C++ applications.

Library: libboxlite Header: boxlite.h C Standard: C11-compatible compiler (GCC/Clang)

API Styles

The SDK provides two API styles:

  1. Simple API (boxlite_simple_*) - Convenience layer for common use cases

    • No runtime setup required
    • Auto-managed runtime
    • Buffered command results
  2. Native API (boxlite_*) - Full-featured, flexible interface

    • Typed CBoxliteOptions configuration
    • Streaming output callbacks
    • Advanced features (volumes, networking, etc.)

Table of Contents


Quick Start

#include <stdio.h>
#include "boxlite.h"

int main() {
    CBoxliteSimple* box = NULL;
    CBoxliteError error = {0};

    // Create box and auto-start it
    if (boxlite_simple_new("python:slim", 0, 0, &box, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        return 1;
    }

    // Run command and get buffered result
    const char* args[] = {"-c", "print('Hello from BoxLite!')", NULL};
    CBoxliteExecResult* result = NULL;

    if (boxlite_simple_run(box, "python", args, 2, &result, &error) == Ok) {
        printf("Output: %s\n", result->stdout_text);
        printf("Exit code: %d\n", result->exit_code);
        boxlite_result_free(result);
    }

    boxlite_simple_free(box);  // Auto-cleanup
    return 0;
}

Native API (Full Control)

#include <stdio.h>
#include "boxlite.h"

void output_callback(const char* text, int is_stderr, void* user_data) {
    FILE* stream = is_stderr ? stderr : stdout;
    fprintf(stream, "%s", text);
}

int main() {
    CBoxliteRuntime* runtime = NULL;
    CBoxHandle* box = NULL;
    CBoxliteError error = {0};

    // Create runtime
    if (boxlite_runtime_new(NULL, NULL, 0, &runtime, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        return 1;
    }

    // Create box with typed options
    CBoxliteOptions* opts = NULL;
    if (boxlite_options_new("alpine:3.19", &opts, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        boxlite_runtime_free(runtime);
        return 1;
    }
    boxlite_options_set_network_enabled(opts);

    if (boxlite_create_box(runtime, opts, &box, &error) != Ok) {
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
        boxlite_error_free(&error);
        boxlite_options_free(opts);
        boxlite_runtime_free(runtime);
        return 1;
    }
    boxlite_options_free(opts);

    // Start command with streaming output, then wait for completion
    int exit_code = 0;
    const char* args[] = {"-la", "/"};
    BoxliteCommand cmd = {.command = "/bin/ls", .args = args, .argc = 2};
    CExecutionHandle* execution = NULL;

    if (boxlite_execute(box, &cmd, output_callback, NULL, &execution, &error) == Ok) {
        if (boxlite_execution_wait(execution, &exit_code, &error) == Ok) {
            printf("\nExit code: %d\n", exit_code);
        }
        boxlite_execution_free(execution);
    }
    if (error.code != Ok) {
        fprintf(stderr, "Error: %s\n", error.message);
        boxlite_error_free(&error);
    }

    // Cleanup
    boxlite_runtime_free(runtime);
    return 0;
}

Building

# Compile with the BoxLite library
gcc -I/path/to/boxlite/sdks/c/include \
    -L/path/to/boxlite/target/release \
    -lboxlite \
    my_program.c -o my_program

# macOS: Set library path
export DYLD_LIBRARY_PATH=/path/to/boxlite/target/release:$DYLD_LIBRARY_PATH

# Linux: Set library path
export LD_LIBRARY_PATH=/path/to/boxlite/target/release:$LD_LIBRARY_PATH

Error Handling

The C SDK introduces structured error handling with error codes and detailed messages.

BoxliteErrorCode

All API functions return BoxliteErrorCode to indicate success or failure type:

typedef enum BoxliteErrorCode {
    Ok = 0,               // Success
    Internal = 1,         // Internal error
    NotFound = 2,         // Resource not found
    AlreadyExists = 3,    // Resource already exists
    InvalidState = 4,     // Invalid state for operation
    InvalidArgument = 5,  // Invalid argument
    Config = 6,           // Configuration error
    Storage = 7,          // Storage error
    Image = 8,            // Image error
    Network = 9,          // Network error
    Execution = 10,       // Execution error
    Stopped = 11,         // Resource stopped
    Engine = 12,          // Engine error
    Unsupported = 13,     // Unsupported operation
    Database = 14,        // Database error
    Portal = 15,          // Portal/communication error
    Rpc = 16,             // RPC error
    RpcTransport = 17,    // RPC transport error
    Metadata = 18,        // Metadata error
    UnsupportedEngine = 19, // Unsupported engine error
} BoxliteErrorCode;

CBoxliteError

Detailed error information for debugging:

typedef struct CBoxliteError {
    BoxliteErrorCode code;  // Error code for programmatic handling
    char* message;          // Detailed message (NULL if none)
} CBoxliteError;

Error Handling Patterns

Pattern 1: Basic Check

CBoxliteError error = {0};
BoxliteErrorCode code = boxlite_simple_new("alpine:3.19", 0, 0, &box, &error);

if (code != Ok) {
    fprintf(stderr, "Error %d: %s\n", error.code, error.message);
    boxlite_error_free(&error);
    return 1;
}

Pattern 2: Switch on Error Code

BoxliteErrorCode code = boxlite_get(runtime, "box-id", &box, &error);

switch (code) {
    case Ok:
        // Success - use box
        break;
    case NotFound:
        fprintf(stderr, "Box not found\n");
        break;
    case InvalidState:
        fprintf(stderr, "Box in invalid state\n");
        break;
    default:
        fprintf(stderr, "Error %d: %s\n", error.code, error.message);
}

boxlite_error_free(&error);

Pattern 3: Retry Logic

int retries = 3;
for (int i = 0; i < retries; i++) {
    code = boxlite_simple_new("alpine:3.19", 0, 0, &box, &error);
    if (code == Ok) break;

    fprintf(stderr, "Retry %d/%d: %s\n", i+1, retries, error.message);
    boxlite_error_free(&error);

    if (code == InvalidArgument || code == Unsupported) {
        break;  // Non-retryable errors
    }
    sleep(1);  // Backoff
}

Simple API

The Simple API provides a streamlined interface for common use cases.

boxlite_simple_new

Create and auto-start a box with sensible defaults.

BoxliteErrorCode boxlite_simple_new(
    const char* image,
    int cpus,
    int memory_mib,
    CBoxliteSimple** out_box,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
imageconst char*OCI image reference (e.g., "python:slim", "alpine:3.19")
cpusintNumber of CPUs (0 = default: 2)
memory_mibintMemory in MiB (0 = default: 512)
out_boxCBoxliteSimple**Output: created box handle
out_errorCBoxliteError*Output: error information

Returns

BoxliteErrorCode - Ok on success, error code on failure.

Example

CBoxliteSimple* box = NULL;
CBoxliteError error = {0};

// Default resources
if (boxlite_simple_new("alpine:3.19", 0, 0, &box, &error) != Ok) {
    fprintf(stderr, "Error: %s\n", error.message);
    boxlite_error_free(&error);
    return 1;
}

// Custom resources
if (boxlite_simple_new("python:slim", 4, 2048, &box, &error) != Ok) {
    // Handle error
}

boxlite_simple_run

Run a command and get buffered result.

BoxliteErrorCode boxlite_simple_run(
    CBoxliteSimple* box,
    const char* command,
    const char* const* args,
    int argc,
    CBoxliteExecResult** out_result,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
boxCBoxliteSimple*Box handle from boxlite_simple_new
commandconst char*Command to execute
argsconst char* const*NULL-terminated array of arguments
argcintNumber of arguments (excluding NULL terminator)
out_resultCBoxliteExecResult**Output: execution result
out_errorCBoxliteError*Output: error information

Result Structure

typedef struct CBoxliteExecResult {
    int exit_code;       // Command exit code
    char* stdout_text;   // Standard output
    char* stderr_text;   // Standard error
} CBoxliteExecResult;

Example

const char* args[] = {"-c", "print('hello')", NULL};
CBoxliteExecResult* result = NULL;

if (boxlite_simple_run(box, "python", args, 2, &result, &error) == Ok) {
    printf("stdout: %s\n", result->stdout_text);
    printf("stderr: %s\n", result->stderr_text);
    printf("exit: %d\n", result->exit_code);
    boxlite_result_free(result);
}

boxlite_simple_free

Free a simple box (auto-stops and removes).

void boxlite_simple_free(CBoxliteSimple* box);

Safe to call with NULL.


boxlite_result_free

Free an execution result.

void boxlite_result_free(CBoxliteExecResult* result);

Safe to call with NULL.


Native API

Runtime Management

boxlite_version

Get BoxLite version string.

const char* boxlite_version(void);

Returns static string (do not free). Example: "0.5.7".


boxlite_runtime_new

Create a new runtime instance.

typedef enum BoxliteRegistryTransport {
    BoxliteRegistryTransportHttps = 0,
    BoxliteRegistryTransportHttp = 1,
} BoxliteRegistryTransport;

typedef struct BoxliteImageRegistry {
    const char* host;
    BoxliteRegistryTransport transport;
    int skip_verify;
    int search;
    const char* username;
    const char* password;
    const char* bearer_token;
} BoxliteImageRegistry;

BoxliteErrorCode boxlite_runtime_new(
    const char* home_dir,
    const BoxliteImageRegistry* image_registries,
    int image_registries_count,
    CBoxliteRuntime** out_runtime,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
home_dirconst char*Path to BoxLite home. NULL = default (~/.boxlite)
image_registriesconst BoxliteImageRegistry*Optional registry transport, TLS, search, and auth settings
image_registries_countintNumber of entries in image_registries
out_runtimeCBoxliteRuntime**Output: runtime handle
out_errorCBoxliteError*Output: error information

Example

CBoxliteRuntime* runtime = NULL;
CBoxliteError error = {0};

// Default configuration
if (boxlite_runtime_new(NULL, NULL, 0, &runtime, &error) != Ok) {
    fprintf(stderr, "Error: %s\n", error.message);
    boxlite_error_free(&error);
    return 1;
}

// Custom registries
BoxliteImageRegistry image_registries[] = {
  {
    .host = "ghcr.io",
    .transport = BoxliteRegistryTransportHttps,
    .skip_verify = 0,
    .search = 1,
    .username = NULL,
    .password = NULL,
    .bearer_token = NULL,
  },
  {
    .host = "registry.example.com",
    .transport = BoxliteRegistryTransportHttps,
    .skip_verify = 0,
    .search = 0,
    .username = "user",
    .password = "password",
    .bearer_token = NULL,
  },
};
if (boxlite_runtime_new("/var/lib/boxlite", image_registries, 2, &runtime, &error) != Ok) {
    // Handle error
}

boxlite_runtime_shutdown

Gracefully stop all running boxes.

BoxliteErrorCode boxlite_runtime_shutdown(
    CBoxliteRuntime* runtime,
    int timeout,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
timeoutintSeconds: 0=default(10), -1=infinite, >0=custom
out_errorCBoxliteError*Output: error information

boxlite_runtime_free

Free a runtime instance.

void boxlite_runtime_free(CBoxliteRuntime* runtime);

Safe to call with NULL. Automatically frees all boxes.


Box Management

boxlite_create_box

Create and auto-start a box.

BoxliteErrorCode boxlite_create_box(
    CBoxliteRuntime* runtime,
    CBoxliteOptions* opts,
    CBoxHandle** out_box,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
runtimeCBoxliteRuntime*Runtime instance
optsCBoxliteOptions*Box options created with boxlite_options_new()
out_boxCBoxHandle**Output: box handle
out_errorCBoxliteError*Output: error information

Example

CBoxliteOptions* opts = NULL;
if (boxlite_options_new("alpine:3.19", &opts, &error) != Ok) {
    // Handle error
}
boxlite_options_set_cpus(opts, 2);
boxlite_options_set_memory(opts, 512);
boxlite_options_set_network_enabled(opts);

CBoxHandle* box = NULL;
if (boxlite_create_box(runtime, opts, &box, &error) != Ok) {
    fprintf(stderr, "Error: %s\n", error.message);
    boxlite_error_free(&error);
}
boxlite_options_free(opts);

boxlite_start_box

Start or restart a stopped box.

BoxliteErrorCode boxlite_start_box(
    CBoxHandle* handle,
    CBoxliteError* out_error
);

boxlite_stop_box

Stop a running box.

BoxliteErrorCode boxlite_stop_box(
    CBoxHandle* handle,
    CBoxliteError* out_error
);

Note: Consumes the handle - do not use after calling.


boxlite_remove

Remove a box.

BoxliteErrorCode boxlite_remove(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    int force,
    CBoxliteError* out_error
);
ParameterTypeDescription
id_or_nameconst char*Box ID (full or prefix) or name
forceintNon-zero to force remove running box

boxlite_get

Reattach to an existing box.

BoxliteErrorCode boxlite_get(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    CBoxHandle** out_handle,
    CBoxliteError* out_error
);

boxlite_box_id

Get box ID string from handle.

char* boxlite_box_id(CBoxHandle* handle);

Important: Caller must free with boxlite_free_string().


boxlite_box_free

Free a box handle.

void boxlite_box_free(CBoxHandle* handle);

Safe to call with NULL. Use when you need to release a box handle without freeing the entire runtime.


Command Execution

boxlite_execute

Start a command with optional streaming output and return an execution handle.

typedef struct BoxliteCommand {
    const char* command;      // Required: command to execute
    const char* const* args;  // Argument array, or NULL
    int argc;                 // Number of entries in args
    const char* const* env_pairs; // [key0, value0, key1, value1, ...], or NULL
    int env_count;            // Number of strings in env_pairs
    const char* workdir;      // Working directory, or NULL
    const char* user;         // User spec (e.g., "nobody", "1000:1000"), or NULL
    double timeout_secs;      // Timeout in seconds (0.0 = no timeout)
    int tty;                  // 0 = no TTY, non-zero = TTY
} BoxliteCommand;

BoxliteErrorCode boxlite_execute(
    CBoxHandle* handle,
    const BoxliteCommand* cmd,
    void (*callback)(const char* text, int is_stderr, void* user_data),
    void* user_data,
    CExecutionHandle** out_execution,
    CBoxliteError* out_error
);

Parameters

ParameterTypeDescription
handleCBoxHandle*Box handle
cmdconst BoxliteCommand*Command descriptor
callbackfunction pointerOptional streaming output callback
user_datavoid*User data passed to callback
out_executionCExecutionHandle**Output: execution handle
out_errorCBoxliteError*Output: error information

Callback Signature

void callback(const char* text, int is_stderr, void* user_data);
ParameterDescription
textOutput text chunk
is_stderr0 for stdout, 1 for stderr
user_dataUser data from boxlite_execute

Example

void output_handler(const char* text, int is_stderr, void* data) {
    FILE* stream = is_stderr ? stderr : stdout;
    fprintf(stream, "%s", text);
}

int exit_code = 0;
const char* args[] = {"-c", "print('hello')"};
BoxliteCommand cmd = {.command = "python", .args = args, .argc = 2};
CExecutionHandle* execution = NULL;
BoxliteErrorCode code = boxlite_execute(
    box,
    &cmd,
    output_handler,
    NULL,
    &execution,
    &error
);

if (code == Ok) {
    code = boxlite_execution_wait(execution, &exit_code, &error);
    boxlite_execution_free(execution);
}
if (code == Ok) {
    printf("Exit code: %d\n", exit_code);
}

Execution Control

BoxliteErrorCode boxlite_execution_write(CExecutionHandle* execution, const char* data, int len, CBoxliteError* out_error);
BoxliteErrorCode boxlite_execution_wait(CExecutionHandle* execution, int* out_exit_code, CBoxliteError* out_error);
BoxliteErrorCode boxlite_execution_kill(CExecutionHandle* execution, CBoxliteError* out_error);
BoxliteErrorCode boxlite_execution_resize_tty(CExecutionHandle* execution, int rows, int cols, CBoxliteError* out_error);
void boxlite_execution_free(CExecutionHandle* execution);

Example: command options

const char* args[] = {"-c", "import os; print(os.getcwd())"};
const char* env[] = {"MY_VAR", "hello"};
BoxliteCommand cmd = {
    .command = "python",
    .args = args,
    .argc = 2,
    .env_pairs = env,
    .env_count = 2,
    .workdir = "/tmp",
    .user = "nobody",
    .timeout_secs = 30.0,
};

int exit_code = 0;
CExecutionHandle* execution = NULL;
BoxliteErrorCode code =
    boxlite_execute(box, &cmd, output_handler, NULL, &execution, &error);
if (code == Ok) {
    code = boxlite_execution_wait(execution, &exit_code, &error);
    boxlite_execution_free(execution);
}

Discovery & Introspection

boxlite_list_info

List all boxes.

BoxliteErrorCode boxlite_list_info(
    CBoxliteRuntime* runtime,
    CBoxInfoList** out_list,
    CBoxliteError* out_error
);

Caller must free out_list with boxlite_free_box_info_list().


boxlite_get_info

Get single box info by ID or name.

BoxliteErrorCode boxlite_get_info(
    CBoxliteRuntime* runtime,
    const char* id_or_name,
    CBoxInfo** out_info,
    CBoxliteError* out_error
);

boxlite_box_info

Get box info from handle.

BoxliteErrorCode boxlite_box_info(
    CBoxHandle* handle,
    CBoxInfo** out_info,
    CBoxliteError* out_error
);

Caller must free out_info with boxlite_free_box_info().

CBoxInfo* info = NULL;
if (boxlite_box_info(box, &info, &error) == Ok) {
    printf("Box %s status: %s\n", info->id, info->status);
    boxlite_free_box_info(info);
}

Metrics

boxlite_runtime_metrics

Get runtime-wide metrics.

BoxliteErrorCode boxlite_runtime_metrics(
    CBoxliteRuntime* runtime,
    CRuntimeMetrics* out_metrics,
    CBoxliteError* out_error
);

boxlite_box_metrics

Get per-box metrics.

BoxliteErrorCode boxlite_box_metrics(
    CBoxHandle* handle,
    CBoxMetrics* out_metrics,
    CBoxliteError* out_error
);

Memory Management

Rules

  1. All allocated strings must be freed

    • boxlite_box_id()boxlite_free_string()
  2. Error structs must be freed

    • CBoxliteErrorboxlite_error_free()
  3. Results must be freed

    • CBoxliteExecResultboxlite_result_free()
    • CBoxInfoboxlite_free_box_info()
    • CBoxInfoListboxlite_free_box_info_list()
    • CImagePullResultboxlite_free_image_pull_result()
    • CImageInfoListboxlite_free_image_info_list()
  4. All cleanup functions are NULL-safe

Functions

boxlite_free_string

Free a string allocated by BoxLite.

void boxlite_free_string(char* str);

boxlite_error_free

Free error struct (message only - struct itself is stack-allocated).

void boxlite_error_free(CBoxliteError* error);

boxlite_box_free

Free a box handle.

void boxlite_box_free(CBoxHandle* handle);

Safe to call with NULL.


Thread Safety

ComponentThread Safety
CBoxliteRuntimeThread-safe
CBoxHandleNOT thread-safe - do not share across threads
CBoxliteSimpleNOT thread-safe - do not share across threads
CallbacksInvoked on the calling thread

Safe Multi-threaded Usage

// CORRECT: Share runtime, create per-thread boxes
void* thread_func(void* arg) {
    CBoxliteRuntime* runtime = (CBoxliteRuntime*)arg;
    CBoxliteError error = {0};
    CBoxliteOptions* opts = NULL;
    CBoxHandle* box = NULL;

    // Each thread creates its own box
    boxlite_options_new("alpine:3.19", &opts, &error);
    boxlite_create_box(runtime, opts, &box, &error);
    boxlite_options_free(opts);
    // Use box in this thread only
    boxlite_stop_box(box, &error);
    return NULL;
}

CBoxliteRuntime* runtime;
boxlite_runtime_new(NULL, NULL, 0, &runtime, &error);

pthread_t threads[4];
for (int i = 0; i < 4; i++) {
    pthread_create(&threads[i], NULL, thread_func, runtime);
}

Platform Requirements

PlatformArchitectureStatusRequirements
macOSARM64 (Apple Silicon)SupportedmacOS 11.0+, Hypervisor.framework
macOSx86_64 (Intel)Not supportedN/A
Linuxx86_64SupportedKVM enabled
LinuxARM64 (aarch64)SupportedKVM enabled
WindowsAnyVia WSL2WSL2 with KVM

Migration from v0.1.x

Error Handling Change

v0.1.x (old):

char* error = NULL;
CBoxliteRuntime* runtime = boxlite_runtime_new(NULL, &error);
if (!runtime) {
    fprintf(stderr, "Error: %s\n", error);
    boxlite_free_string(error);
    return 1;
}

v0.2.0 (new):

CBoxliteRuntime* runtime = NULL;
CBoxliteError error = {0};
BoxliteErrorCode code = boxlite_runtime_new(NULL, NULL, 0, &runtime, &error);
if (code != Ok) {
    fprintf(stderr, "Error %d: %s\n", error.code, error.message);
    boxlite_error_free(&error);
    return 1;
}

Execute Change

v0.1.x:

int exit_code = old_execute_api_returning_exit_code(...);
if (exit_code < 0) {
    // Error
}

v0.2.0:

int exit_code = 0;
const char* args[] = {"hello"};
BoxliteCommand cmd = {.command = "echo", .args = args, .argc = 1};
CExecutionHandle* execution = NULL;
BoxliteErrorCode code =
    boxlite_execute(box, &cmd, callback, NULL, &execution, &error);
if (code == Ok) {
    code = boxlite_execution_wait(execution, &exit_code, &error);
    boxlite_execution_free(execution);
}
if (code != Ok) {
    // Error
}

Migration Checklist

  • Replace char* error = NULL with CBoxliteError error = {0}
  • Initialize output pointers to NULL (e.g., CBoxliteRuntime* runtime = NULL)
  • Update all function calls to use output parameters
  • Replace return value checks with BoxliteErrorCode checks
  • Replace boxlite_free_string(error) with boxlite_error_free(&error)
  • Create boxes with CBoxliteOptions

API Summary

FunctionDescription
boxlite_version()Get version string
boxlite_runtime_new()Create runtime
boxlite_runtime_shutdown()Graceful shutdown
boxlite_runtime_free()Free runtime
boxlite_runtime_metrics()Get runtime metrics
boxlite_create_box()Create box
boxlite_start_box()Start/restart box
boxlite_stop_box()Stop box
boxlite_remove()Remove box
boxlite_get()Reattach to box
boxlite_box_id()Get box ID
boxlite_box_free()Free box handle
boxlite_box_info()Get box info
boxlite_box_metrics()Get box metrics
boxlite_execute()Execute command
boxlite_list_info()List all boxes
boxlite_get_info()Get box info by ID
boxlite_simple_new()Create simple box
boxlite_simple_run()Run command (simple)
boxlite_simple_free()Free simple box
boxlite_result_free()Free exec result
boxlite_free_string()Free string
boxlite_error_free()Free error

Common Patterns

Streaming Output

void output_callback(const char* text, int is_stderr, void* user_data) {
    FILE* stream = is_stderr ? stderr : stdout;
    fprintf(stream, "%s", text);
}

int exit_code = 0;
const char* args[] = {"-c", "print('hello')"};
BoxliteCommand cmd = {.command = "python", .args = args, .argc = 2};
CExecutionHandle* execution = NULL;
if (boxlite_execute(box, &cmd, output_callback, NULL, &execution, &error) == Ok) {
    boxlite_execution_wait(execution, &exit_code, &error);
    boxlite_execution_free(execution);
}

Reattach to Box

// Get box ID
char* box_id = boxlite_box_id(box);

// Later, in different process:
CBoxHandle* box2 = NULL;
boxlite_get(runtime, box_id, &box2, &error);

boxlite_free_string(box_id);

Get Box Info

CBoxInfo* info = NULL;
if (boxlite_box_info(box, &info, &error) == Ok) {
    printf("Box %s status: %s\n", info->id, info->status);
    boxlite_free_box_info(info);
}

Common Mistakes

Uninitialized error struct

CBoxliteError error;       // Wrong: uninitialized
CBoxliteError error = {0}; // Correct: zero-initialized

Forgetting to free error

if (code != Ok) {
    printf("Error: %s\n", error.message);
    return 1;                       // Wrong: memory leak
}

if (code != Ok) {
    printf("Error: %s\n", error.message);
    boxlite_error_free(&error);     // Correct
    return 1;
}

Forgetting to free result structs

CBoxInfoList* list;
boxlite_list_info(runtime, &list, &error);
// Wrong: forgot to free

CBoxInfoList* list;
boxlite_list_info(runtime, &list, &error);
boxlite_free_box_info_list(list);  // Correct

CMake

cmake_minimum_required(VERSION 3.15)
project(my_app)

set(BOXLITE_INCLUDE "/path/to/boxlite/sdks/c/include")
set(BOXLITE_LIB_DIR "/path/to/boxlite/target/release")

include_directories(${BOXLITE_INCLUDE})

add_executable(my_app main.c)
target_link_libraries(my_app ${BOXLITE_LIB_DIR}/libboxlite.dylib)

Direct Compilation

# macOS
gcc -o myapp myapp.c \
    -I/path/to/boxlite/sdks/c/include \
    -L/path/to/boxlite/target/release \
    -lboxlite

export DYLD_LIBRARY_PATH=/path/to/boxlite/target/release:$DYLD_LIBRARY_PATH
./myapp

# Linux
gcc -o myapp myapp.c \
    -I/path/to/boxlite/sdks/c/include \
    -L/path/to/boxlite/target/release \
    -lboxlite

export LD_LIBRARY_PATH=/path/to/boxlite/target/release:$LD_LIBRARY_PATH
./myapp

See Also