Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Exemples C compilables

Trois programmes complets, compilés contre le header committé et liés à libair_base.so. Les sources autonomes vivent dans docs/guides/abi-c/examples/ et sont compilées (advisory) par scripts/build-docs.sh quand cc et la cdylib sont présents — preuve que le header et la lib s’emploient exactement comme décrit.

Compiler & lier (rappel)

cargo build -p air-base-capi                  # → target/debug/libair_base.so

cc docs/guides/abi-c/examples/<exemple>.c \
   -I crates/air-base-capi/include \
   -L target/debug -lair_base \
   -Wl,-rpath,target/debug \
   -o <exemple>

Voir Mise en route pour le détail des options.

(a) UUID : new_v7to_hyphenatedparse

Round-trip complet sur un POD ; rien à libérer (buffer sur la pile).

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

int main(void) {
  AirUuid u;
  if (air_uuid_new_v7(&u) != AIR_STATUS_OK) return 1;       /* `&u` emprunté +0 */

  char text[AIR_UUID_HYPHENATED_LEN];                       /* buffer appelant (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;
}

Points clés : text est votre buffer (catégorie 2) ; trop petit ⇒ AIR_STATUS_BUFFER_TOO_SMALL, rien écrit. Aucune air_*_free.

(b) Logging : openfieldsemitclose

Le seul exemple avec des handles possédés (+1) : il doit libérer dans l’ordre inverse de l’acquisition.

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

int main(void) {
  AirLog *log = NULL;
  AirStatus st = air_log_open(NULL /* journal par défaut */, &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);                                /* libère l'acquis */
    return 1;
  }

  air_log_fields_add(fields, "REQUEST_ID", "abc-123"); /* fields emprunté-mut +0 */
  air_log_emit(log, AIR_LOG_LEVEL_INFO, "hello depuis C", fields); /* tout +0 */

  air_log_fields_free(fields);   /* libère le builder */
  air_log_close(log);            /* libère le logger  */
  return 0;
}

Points clés : open/new rendent des handles possédés → libération obligatoire (close/free). emit emprunte tout (+0). Sur l’échec de fields_new, on libère le log déjà acquis avant de sortir (pas de fuite). AirLogFields est mono-thread (cf. Thread-safety).

(c) Temps : nowelapsedas_secs_f64

Mesure d’écoulement monotone sur des POD ; réentrant, rien à libérer.

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

int main(void) {
  AirInstant start;
  if (air_instant_now(&start) != AIR_STATUS_OK) return 1;  /* valeur absolue opaque */

  /* ... travail à mesurer ... */

  AirDuration d;
  if (air_instant_elapsed(&start, &d) != AIR_STATUS_OK) return 1;  /* saturé à 0 */

  double secs;
  if (air_duration_as_secs_f64(&d, &secs) != AIR_STATUS_OK) return 1;
  printf("écoulé = %.9f s (%lld s + %u ns)\n",
         secs, (long long)d.seconds, d.nanoseconds);
  return 0;
}

Points clés : la valeur absolue d’un AirInstant est opaque — seules les différences ont un sens. air_instant_elapsed est saturé à zéro si start est dans le futur (jamais de durée négative). Tout est POD local, donc réentrant.

Et si cc est absent ?

Ces exemples sont fournis en bloc ci-dessus (lisibles sans rien compiler) ; la compilation par build-docs.sh est advisory : son absence ne casse jamais le build de la doc. La conformité « comme un vrai consommateur C » est par ailleurs vérifiée par le test ABI de la crate (tests/abi/conformance.c).

English version: Compilable C examples.