Compilable C examples
Three complete programs, compiled against the committed header and linked to
libair_base.so. The standalone sources live in
docs/guides/abi-c/examples/
and are compiled (advisory) by scripts/build-docs.sh when cc and the cdylib
are present — proof that the header and the lib are used exactly as described.
Compile & link (reminder)
cargo build -p air-base-capi # → target/debug/libair_base.so
cc docs/guides/abi-c/examples/<example>.c \
-I crates/air-base-capi/include \
-L target/debug -lair_base \
-Wl,-rpath,target/debug \
-o <example>
See Getting started for the option details.
(a) UUID: new_v7 → to_hyphenated → parse
A full round-trip on a POD; nothing to free (stack buffer).
#include <stdio.h>
#include "air_base.h"
int main(void) {
AirUuid u;
if (air_uuid_new_v7(&u) != AIR_STATUS_OK) return 1; /* `&u` borrowed +0 */
char text[AIR_UUID_HYPHENATED_LEN]; /* caller buffer (37) */
if (air_uuid_to_hyphenated(&u, text, sizeof text) != AIR_STATUS_OK) return 1;
printf("uuid v7 = %s\n", text);
AirUuid back;
if (air_uuid_parse(text, &back) != AIR_STATUS_OK) return 1;
return 0;
}
Key points: text is your buffer (category 2); too small ⇒
AIR_STATUS_BUFFER_TOO_SMALL, nothing written. No air_*_free.
(b) Logging: open → fields → emit → close
The only example with owned handles (+1): it must free in the reverse order of acquisition.
#include <stdio.h>
#include "air_base.h"
int main(void) {
AirLog *log = NULL;
AirStatus st = air_log_open(NULL /* default journal */, &log); /* +1 */
if (st != AIR_STATUS_OK) {
fprintf(stderr, "air_log_open: %s\n", air_status_message(st));
return 1;
}
AirLogFields *fields = NULL;
if (air_log_fields_new(&fields) != AIR_STATUS_OK) { /* +1 */
air_log_close(log); /* free what was acquired */
return 1;
}
air_log_fields_add(fields, "REQUEST_ID", "abc-123"); /* fields borrowed-mut +0 */
air_log_emit(log, AIR_LOG_LEVEL_INFO, "hello from C", fields); /* all +0 */
air_log_fields_free(fields); /* free the builder */
air_log_close(log); /* free the logger */
return 0;
}
Key points: open/new return owned handles → mandatory release
(close/free). emit borrows everything (+0). On fields_new failure, the
already-acquired log is freed before returning (no leak). AirLogFields is
single-threaded (see Thread-safety).
(c) Time: now → elapsed → as_secs_f64
Monotonic elapsed-time measurement on POD; reentrant, nothing to free.
#include <stdio.h>
#include "air_base.h"
int main(void) {
AirInstant start;
if (air_instant_now(&start) != AIR_STATUS_OK) return 1; /* absolute value opaque */
/* ... work to be measured ... */
AirDuration d;
if (air_instant_elapsed(&start, &d) != AIR_STATUS_OK) return 1; /* saturated at 0 */
double secs;
if (air_duration_as_secs_f64(&d, &secs) != AIR_STATUS_OK) return 1;
printf("elapsed = %.9f s (%lld s + %u ns)\n",
secs, (long long)d.seconds, d.nanoseconds);
return 0;
}
Key points: an AirInstant’s absolute value is opaque — only differences
matter. air_instant_elapsed is saturated at zero if start is in the future
(never a negative duration). Everything is local POD, hence reentrant.
What if cc is absent?
These examples are provided inline above (readable without compiling anything); the
compilation by build-docs.sh is advisory: its absence never breaks the doc build.
Conformance “like a real C consumer” is additionally verified by the crate’s ABI test
(tests/abi/conformance.c).
Version française : Exemples C compilables.