# Getting Started with C API

## Prerequisites

- C99 compatible compiler
- The Face Verification Library shared library (`.so` / `.dylib` / `.dll`)

## Installation

Extract the SDK contents, include `faceverifier_c.h` from the `include` folder and link `libFaceVerificationLibrary` to your C project.

## Quick Start Example

```c
#include "faceverifier_c.h"
#include <stdio.h>
#include <stdlib.h>

/* Callback for face detection */
void on_faces_detected(void* user_data, FVLFaceArray* faces, const char* error_msg) {
    if (error_msg) {
        fprintf(stderr, "Detection error: %s\n", error_msg);
        return;
    }
    printf("Detected %d face(s)\n", faces->count);

    /* Process each face... */
    for (int i = 0; i < faces->count; i++) {
        FVLBoundingBox bbox = fvl_face_bounding_box(faces->faces[i]);
        printf("  Face %d: (%d, %d, %d, %d)\n", i, bbox.x, bbox.y, bbox.width, bbox.height);
    }
}

int main() {
    char* error = NULL;

    /* Create verifier */
    FVLFaceVerifier* verifier = fvl_face_verifier_new("model/model.realZ", 0, &error);
    if (!verifier) {
        fprintf(stderr, "Failed to create verifier: %s\n", error);
        free(error);
        return 1;
    }

    /* Detect faces (async with callback) */
    FVLImageHeader header = {image_data, width, height, stride, FVLImageFormatRGB};
    fvl_face_verifier_detect_faces(verifier, &header, on_faces_detected, NULL);

    /* Clean up */
    fvl_face_verifier_free(verifier);
    return 0;
}
```

## Common Patterns

### Error Handling

Functions that can fail accept a `char** errorMessage` output parameter. On failure, the function returns `NULL` and sets the error message. The caller must free the error string:

```c
char* error = NULL;
FVLFaceVerifier* verifier = fvl_face_verifier_new("model.realZ", 0, &error);
if (!verifier) {
    fprintf(stderr, "Error: %s\n", error);
    free(error);
}
```

Pass `NULL` for `errorMessage` if you don't need the error details.

### Memory Management

| Function Returns | Must Free? | How |
|------------------|------------|-----|
| `fvl_face_verifier_new()` | Yes | `fvl_face_verifier_free()` |
| `fvl_face_new()` | Yes | `fvl_face_free()` |
| `fvl_face_copy()` | Yes | `fvl_face_free()` |
| `fvl_face_landmarks()` | Yes | `free()` |
| `fvl_face_verifier_get_model_name()` | Yes | `free()` |
| `fvl_face_verifier_get_sdk_version_string()` | Yes | `free()` |
| `errorMessage` output parameter | Yes | `free()` |
| Callback parameters (`faces`, `embedding`, `error_msg`) | No | Valid only during callback |

### Callbacks

Async operations use callbacks. The `result` and `error_msg` parameters are only valid during the callback — copy any data you need to retain:

```c
void on_embedding(void* user_data, FVLFloatArray* embedding, const char* error_msg) {
    if (error_msg) {
        /* handle error */
        return;
    }
    /* Copy embedding data if needed beyond callback lifetime */
    float* my_embedding = malloc(embedding->count * sizeof(float));
    memcpy(my_embedding, embedding->data, embedding->count * sizeof(float));
}
```

## Next Steps

- [C API Reference](../api-reference/c.md)
