Skip to content
Arxo Arxo

FFI (C-Compatible) API

The arxo-engine exposes a minimal C-compatible FFI for integration with any language that supports C bindings. The engine is loaded as a shared library; you pass a project path and a JSON config string and receive a JSON result string.

The FFI can be used from:

  • C/C++ - Direct usage
  • Go - Via cgo
  • Zig - Via @cInclude
  • Swift - Via Swift’s C interop
  • Any language with C FFI support

Use the pre-compiled library for your platform. Naming follows the pattern {prefix}arxo_engine.{ext}:

PlatformFileArchitecture
Linuxlibarxo_engine.sox86_64, ARM64
macOSlibarxo_engine.dylibx86_64, ARM64 (Apple Silicon)
Windowsarxo_engine.dllx86_64

The engine exports exactly three functions. There are no opaque handles: you load the library, call these functions, and free any returned strings.

arxo_engine.h
#ifndef ARCH0_ENGINE_H
#define ARCH0_ENGINE_H
#ifdef __cplusplus
extern "C" {
#endif
// Returns engine version string. Caller must free with arxo_free_string.
// Never returns NULL.
char* arxo_version(void);
// Run analysis.
// path - Project root path (UTF-8, null-terminated)
// config_json - Full config as JSON string (see Configuration)
// license - License key or NULL for default/env
// Returns JSON string with results and violations, or NULL on error.
// Caller must free non-NULL result with arxo_free_string.
char* arxo_analyze(const char* path, const char* config_json, const char* license);
// Free a string returned by arxo_version or arxo_analyze.
void arxo_free_string(char* s);
#ifdef __cplusplus
}
#endif
#endif
FunctionReturnsOwnership
arxo_version()Version string (e.g. "0.1.0")Caller frees with arxo_free_string
arxo_analyze(path, config_json, license)JSON result string, or NULL on errorCaller frees non-NULL with arxo_free_string
arxo_free_string(s)void

On error, arxo_analyze returns NULL (e.g. invalid config, parse failure, missing license). Error details are not exposed via the FFI; ensure config and path are valid and that the license (if required) is provided.

#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char* path = "./my-project";
const char* config_json = "{\"metric_preset\": \"quick\"}";
const char* license = getenv("ARCH0_LICENSE_KEY"); /* or NULL */
char* version = arxo_version();
printf("Engine version: %s\n", version);
arxo_free_string(version);
char* result_json = arxo_analyze(path, config_json, license);
if (!result_json) {
fprintf(stderr, "Analysis failed\n");
return 1;
}
printf("Result: %s\n", result_json);
arxo_free_string(result_json);
return 0;
}

Compile and run:

Terminal window
gcc -o analyze main.c -L. -larxo_engine -I.
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH # Linux
# or
export DYLD_LIBRARY_PATH=.:$DYLD_LIBRARY_PATH # macOS
./analyze
package main
/*
#cgo LDFLAGS: -L. -larxo_engine
#include <stdlib.h>
extern char* arxo_version(void);
extern char* arxo_analyze(const char* path, const char* config_json, const char* license);
extern void arxo_free_string(char* s);
*/
import "C"
import (
"fmt"
"os"
"unsafe"
)
func main() {
path := C.CString("./my-project")
config := C.CString(`{"metric_preset":"quick"}`)
var license *C.char
if k := os.Getenv("ARCH0_LICENSE_KEY"); k != "" {
license = C.CString(k)
}
defer C.free(unsafe.Pointer(path))
defer C.free(unsafe.Pointer(config))
if license != nil {
defer C.free(unsafe.Pointer(license))
}
v := C.arxo_version()
fmt.Println("Version:", C.GoString(v))
C.arxo_free_string(v)
result := C.arxo_analyze(path, config, license)
if result == nil {
fmt.Fprintln(os.Stderr, "Analysis failed")
os.Exit(1)
}
defer C.arxo_free_string(result)
fmt.Println("Result:", C.GoString(result))
}
import ctypes
import json
import os
lib = ctypes.CDLL("./libarxo_engine.so") # or .dylib / .dll
lib.arxo_version.argtypes = []
lib.arxo_version.restype = ctypes.c_char_p
lib.arxo_analyze.argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_char_p]
lib.arxo_analyze.restype = ctypes.c_char_p
lib.arxo_free_string.argtypes = [ctypes.c_char_p]
lib.arxo_free_string.restype = None
version = lib.arxo_version()
print("Version:", version.decode())
lib.arxo_free_string(version)
path = b"./my-project"
config_json = b'{"metric_preset":"quick"}'
license_key = os.environ.get("ARCH0_LICENSE_KEY", "").encode() or None
result = lib.arxo_analyze(path, config_json, license_key)
if result is None:
raise RuntimeError("Analysis failed")
data = json.loads(result.decode())
lib.arxo_free_string(result)
print("Results:", data)

config_json must be a JSON string matching the engine’s config schema. Minimal example:

{
"metric_preset": "quick",
"data": {
"language": "auto",
"import_graph": { "exclude": ["node_modules", "dist"] }
},
"report": { "format": "json" }
}

See Configuration for all options. Pass the same structure as you would in YAML, serialized to JSON.

When arxo_analyze returns non-NULL, the string is a JSON object with at least:

  • results - Array of metric results (id, value, evidence, etc.)
  • violations - Array of policy violations (metric, threshold, message, etc.)

Exact fields depend on config (metrics enabled, report format). Parse the JSON in your language to inspect results and violations.

  • Memory: You must call arxo_free_string on every non-NULL string returned by arxo_version or arxo_analyze. Do not free NULL.
  • Thread safety: The library is not guaranteed thread-safe. Use one process per analysis or serialize calls (e.g. one engine load per thread if documented safe for your build).
  • Linux: LD_LIBRARY_PATH or install under a path searched by the dynamic linker.
  • macOS: DYLD_LIBRARY_PATH or install under a standard lib path.
  • Windows: Same directory as the executable, or a directory in PATH.
error while loading shared libraries: libarxo_engine.so: cannot open shared object file

Set the library path:

Terminal window
export LD_LIBRARY_PATH=/path/to/lib:$LD_LIBRARY_PATH # Linux
export DYLD_LIBRARY_PATH=/path/to/lib:$DYLD_LIBRARY_PATH # macOS
  • Verify path exists and is readable.
  • Verify config_json is valid JSON and matches the config schema.
  • If your deployment requires a license, set ARCH0_LICENSE_KEY or pass a non-NULL license string.