---
title: "@cImport em Zig — Referência e Exemplos"
url: "https://ziglang.com.br/builtins/@cimport-em-zig-refer%C3%AAncia-e-exemplos/"
markdown_url: "https://ziglang.com.br/builtins/@cimport-em-zig-refer%C3%AAncia-e-exemplos.MD"
description: "Referência completa do @cImport/@cInclude em Zig. Importe cabeçalhos C diretamente para uso em Zig sem bindings manuais. Exemplos pt-BR."
date: "2026-02-21"
author: "Zig Brasil"
---

# @cImport em Zig — Referência e Exemplos

Referência completa do @cImport/@cInclude em Zig. Importe cabeçalhos C diretamente para uso em Zig sem bindings manuais. Exemplos pt-BR.


# @cImport / @cInclude em Zig

O `@cImport` importa cabeçalhos C diretamente para Zig, permitindo chamar funções C sem escrever bindings manuais. Dentro do bloco `@cImport`, use `@cInclude` para incluir headers, `@cDefine` para definir macros e `@cUndef` para desdefini-las. O compilador Zig traduz automaticamente as declarações C para tipos Zig equivalentes.

## Sintaxe

```zig
@cImport(comptime expr: void) type
@cInclude(comptime path: []const u8) void
@cDefine(comptime name: []const u8, comptime value: []const u8) void
@cUndef(comptime name: []const u8) void
```

## Parâmetros

- **@cImport**: Recebe um bloco de expressões comptime que configuram quais headers importar.
- **@cInclude**: Caminho do header C a incluir (como `#include` do C).
- **@cDefine**: Define uma macro (como `#define` do C).
- **@cUndef**: Remove definição de macro.

## Valor de retorno

`@cImport` retorna um `type` — a struct que contém todas as declarações públicas traduzidas dos headers C.

## Exemplos práticos

### Exemplo 1: Importar a biblioteca C padrão

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

pub fn main() void {
    _ = c.printf("Hello from C! %d\n", @as(c_int, 42));
}
```

### Exemplo 2: Usar math.h

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

pub fn main() void {
    const raiz = c.sqrt(144.0);
    std.debug.print("sqrt(144) = {d}\n", .{raiz}); // 12.0

    const absoluto = c.abs(-42);
    std.debug.print("abs(-42) = {}\n", .{absoluto}); // 42
}
```

### Exemplo 3: Importar biblioteca externa com defines

```zig
const c = @cImport({
    @cDefine("NCURSES_WIDECHAR", "1");
    @cInclude("ncurses.h");
});

pub fn main() void {
    _ = c.initscr();
    _ = c.printw("Hello, ncurses from Zig!\n");
    _ = c.refresh();
    _ = c.getch();
    _ = c.endwin();
}
```

## Configuração no build.zig

Para usar `@cImport` com bibliotecas externas, configure os caminhos no `build.zig`:

```zig
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe = b.addExecutable(.{
        .name = "app",
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
    });

    // Linkar com biblioteca C
    exe.linkLibC();
    exe.linkSystemLibrary("ncurses");

    // Adicionar caminhos de include se necessário
    exe.addIncludePath(b.path("include"));

    b.installArtifact(exe);
}
```

## Funções Auxiliares

| Função | Descrição |
|--------|-----------|
| `@cImport(...)` | Iniciar bloco de importação C |
| `@cInclude("header.h")` | Incluir header (como #include) |
| `@cDefine("MACRO", "valor")` | Definir macro de pré-processador |
| `@cUndef("MACRO")` | Remover definição de macro |

## Casos de uso comuns

1. **Bibliotecas C existentes**: Usar SQLite, OpenSSL, SDL, etc. diretamente de Zig.
2. **APIs do sistema**: Acessar syscalls e interfaces do OS.
3. **Migração gradual**: Chamar código C legado enquanto migra para Zig.
4. **Protótipos rápidos**: Usar bibliotecas C sem escrever wrappers manuais.

## Como o @cImport funciona internamente

O Zig invoca o Clang como biblioteca para parsear os cabeçalhos C e gera um módulo Zig equivalente. Esse processo acontece em tempo de compilação. O módulo gerado fica em cache e não precisa ser reprocessado a cada compilação se os headers não mudarem.

Tipos C são mapeados para tipos Zig equivalentes:

| Tipo C | Tipo Zig |
|--------|----------|
| `int` | `c_int` |
| `unsigned int` | `c_uint` |
| `long` | `c_long` |
| `char *` | `[*c]u8` |
| `void *` | `?*anyopaque` |
| `size_t` | `usize` |
| `bool` (C99) | `bool` |
| ponteiro de função | ponteiro de função Zig |

## Lidando com ponteiros C (*[c])

O tipo `[*c]T` representa ponteiros C — que podem ser null, unitários ou apontar para arrays. Ao usar funções C que retornam esses ponteiros, verifique null antes de usar:

```zig
const c = @cImport(@cInclude("string.h"));

pub fn main() !void {
    const str = "hello world";
    const pos = c.strchr(str.ptr, 'w');

    if (pos == null) {
        return error.NaoEncontrado;
    }

    // pos é [*c]u8, não null, usar com cuidado
    const resultado: []const u8 = std.mem.span(pos);
    _ = resultado;
}
```

## Macros C e limitações

`@cImport` lida com funções C e constantes, mas **macros C complexas não são traduzidas automaticamente**. Macros simples que definem constantes funcionam. Macros que são pseudo-funções frequentemente falham:

```zig
// Isso funciona: macro que define constante
// #define MAX_SIZE 1024
// -> c.MAX_SIZE == 1024

// Isso pode não funcionar: macro-função
// #define MIN(a, b) ((a) < (b) ? (a) : (b))
// -> c.MIN pode não existir

// Solução: reescrever em Zig
fn min(a: anytype, b: anytype) @TypeOf(a, b) {
    return if (a < b) a else b;
}
```

Use `zig translate-c header.h` na linha de comando para ver como o Zig traduz um header e identificar o que está disponível.

## Boas práticas

**Isolar o @cImport em um único arquivo**: Em vez de espalhar `@cImport` pelo código, crie um arquivo `c.zig` com todas as importações C e importe esse módulo nos outros arquivos. Isso facilita manutenção e compilação incremental.

```zig
// c.zig
pub const c = @cImport({
    @cInclude("sqlite3.h");
    @cInclude("openssl/ssl.h");
});

// main.zig
const c = @import("c.zig").c;
```

## Erros comuns

**Esquecer de linkar a biblioteca**: `@cImport` resolve os tipos, mas você ainda precisa de `exe.linkSystemLibrary("nome")` no `build.zig` para que o linker encontre as implementações.

**Usar ponteiros C sem verificar null**: Funções C retornam `[*c]T` ou `?*T` que podem ser null. Verifique sempre antes de dereferenciar.

## Perguntas Frequentes

**Posso usar @cImport com headers locais do meu projeto?**

Sim. Use `exe.addIncludePath(b.path("include"))` no `build.zig` para adicionar diretórios de include, e então `@cInclude("meu_header.h")` funcionará normalmente.

**@cImport é mais lento que bindings manuais?**

Em termos de performance do binário gerado, não há diferença — o código C compilado é o mesmo. O tempo de compilação pode ser um pouco maior na primeira vez, mas o resultado é cacheado.

## Builtins relacionados

- [@import](/builtins/import/) — Importar módulos Zig
- [@embedFile](/builtins/embed-file/) — Incorporar arquivos no binário
- [@ptrCast](/builtins/ptr-cast/) — Converter ponteiros entre tipos Zig e C

## Tutoriais relacionados

- [Zig e C: Interoperabilidade](/tutoriais/zig-c-interoperabilidade/)
- [Zig Build System](/tutoriais/zig-build-system/)
- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
