Using C
One of Zig’s strengths is that it makes it easy to call libraries written in C. In Zig 0.17, the way to do that is to use the translate-c tool to automatically translate C to Zig and then build everything with zig build.
Let’s start with a Hello World program that uses the
printf C function. The Zig code is pretty simple:
const c = @import("c");
pub fn main() void {
// We call `printf` like any other function. It
// returns the number of bytes printed, which we
// ignore here.
_ = c.printf("Hello, world!\n");
}We need a C header file that declares the functions we want to call:
/* hello.h */
#include <stdio.h>Next, we need a build.zig to tell Zig how to build
everything:
const std = @import("std");
// A Translator is the entry point for translate_c:
const Translator = @import("translate_c").Translator;
pub fn build(b: *std.Build) void {
const root_source_file = b.path("main.zig");
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// We’ll set up translation for hello.h...
const translate_c = b.dependency("translate_c", .{});
const translator: Translator = .init(translate_c, .{
.c_source_file = b.path("hello.h"),
.target = target,
.optimize = optimize,
});
const exe = b.addExecutable(.{
.name = "addition",
.root_module = b.createModule(.{
.root_source_file = root_source_file,
.target = target,
.optimize = optimize,
// and make the translated code available:
.imports = &.{
.{
.name = "c",
.module = translator.mod,
},
},
}),
});
b.installArtifact(exe);
const run_step = b.step("run", "Run the program");
const run_exe = b.addRunArtifact(exe);
run_step.dependOn(&run_exe.step);
}Finally, we’ll get the translate-c library with zig fetch:
$ zig fetch --save git+https://codeberg.org/ziglang/translate-c#zig-0.17.x
info: resolved ref "zig-0.17.x" to commit cfac21f3199b2b02ce3fd7db652aa456421fe4ab
Now we can build and run it with normal Zig tooling:
$ zig build run
Hello, world!
Next example: C Types.