# `@cImport`

### `@cImport`

Writing every C declaration by hand is tedious. Zig can read C headers directly.

The usual form is:

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

This creates a namespace named `c`. Declarations from the C header are available through that namespace.

A complete program:

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

pub fn main() void {
    _ = c.puts("hello from C");
}
```

Run it:

```sh
zig run main.zig -lc
```

The call:

```zig
c.puts("hello from C")
```

uses the C function declared in `stdio.h`.

The return value is assigned to `_` because `puts` returns an `int`, and Zig does not allow an ignored value unless the programmer says so.

`@cImport` may include more than one header:

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

It may also define macros before including a header:

```zig
const c = @cImport({
    @cDefine("_GNU_SOURCE", {});
    @cInclude("stdio.h");
});
```

The block inside `@cImport` is not ordinary runtime code. It is evaluated by the compiler while translating C declarations into Zig declarations.

Header search paths are passed to the compiler:

```sh
zig build-exe main.zig -Iinclude -lc
```

A header in `include/foo.h` can then be imported:

```zig
const c = @cImport({
    @cInclude("foo.h");
});
```

Use `@cImport` when the C API is large or when the declarations must track a real header file.

Use `extern fn` when the API is small and explicit declarations are clearer.

