# Interoperating with C — Zig

Source: https://www.geekswithgeeks.com/en/zig/s-cinterop

> Call C libraries from Zig and expose Zig functions to C.

## Seamless C interop

Zig is designed to work with the enormous C ecosystem directly. **`@cImport`** with `@cInclude` translates C headers into Zig declarations at compile time, so you can call C functions, use C structs and constants without writing bindings (the Zig team plans to move this to the build system via `addTranslateC`, so newer code may use that instead). Link libraries with `-lc` (libc) or `-l<name>`, or in `build.zig` with `linkLibC()` and `linkSystemLibrary("sqlite3")`. C types map to Zig types: `c_int`, `c_long`, `[*c]T` (C pointers, which may be null and have unknown length) and null-terminated strings `[*:0]const u8`. Convert C pointers to slices with `std.mem.span`. In the other direction, **`export fn`** makes a Zig function callable from C with the C ABI, and `extern struct` gives C-compatible layout, so Zig can build C libraries or replace C modules incrementally. **`zig translate-c`** converts C code to Zig for inspection. Zig can also **compile C and C++ source files** as part of a build, which lets projects mix languages with one toolchain.

## Calling C and exporting to C

@cImport for libc and math, and an exported function.

```zig
const std = @import("std");
const c = @cImport({
    @cInclude("stdio.h");
    @cInclude("math.h");
    @cInclude("string.h");
});

// Callable from C as: unsigned long long gst_paise(unsigned long long);
export fn gst_paise(amount: u64) u64 {
    return amount + (amount * 18 + 50) / 100;
}

pub fn main() void {
    _ = c.printf("sqrt(2) = %.4f\n", c.sqrt(2.0));

    const c_name: [*:0]const u8 = "Asha";                  // null-terminated, like a C string
    const len = c.strlen(c_name);
    const slice: []const u8 = std.mem.span(c_name);       // C string to Zig slice
    std.debug.print("strlen={d} slice={s} gst={d}\n", .{ len, slice, gst_paise(10_000) });
}

// zig run main.zig -lc
// or in build.zig: exe.root_module.link_libc = true;  (older versions: exe.linkLibC())
```

## A fluent interpreter at the border

@cImport is an interpreter who reads C headers fluently and translates them on the spot, so Zig code can talk to decades of C libraries without anyone writing a phrasebook (bindings) by hand.

**Quiz:** What does `export fn` do in Zig?

- [ ] Makes a function public within the file
- [x] Makes the function callable from C with the C ABI and an unmangled name
- [ ] Runs the function at compile time
- [ ] Exports it to JavaScript only

*Answer:* Makes the function callable from C with the C ABI and an unmangled name. export gives a Zig function C linkage so other languages can call it.
