@cImport em Zig — Referência e Exemplos

@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

@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

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

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

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:

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çãoDescriçã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.

Builtins relacionados

  • @import — Importar módulos Zig
  • @embedFile — Incorporar arquivos no binário
  • @ptrCast — Converter ponteiros entre tipos Zig e C

Tutoriais relacionados

Continue aprendendo Zig

Explore mais tutoriais e artigos em português para dominar a linguagem Zig.