@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
#includedo C). - @cDefine: Define uma macro (como
#definedo 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çã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
- Bibliotecas C existentes: Usar SQLite, OpenSSL, SDL, etc. diretamente de Zig.
- APIs do sistema: Acessar syscalls e interfaces do OS.
- Migração gradual: Chamar código C legado enquanto migra para Zig.
- 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