पाठ 17 / 25

Interoperating with C

Call C libraries from Zig and expose Zig functions to C.

Seamless C interop

Zig is designed to work with the enormous C ecosystem directly. @cImport with @cInclude translates C headers into Zig declarations at compile time, so you can call C functions, use C structs and constants without writing bindings (the Zig team plans to move this to the build system via addTranslateC, so newer code may use that instead). Link libraries with -lc (libc) or -l<name>, or in build.zig with linkLibC() and linkSystemLibrary("sqlite3"). C types map to Zig types: c_int, c_long, [*c]T (C pointers, which may be null and have unknown length) and null-terminated strings [*:0]const u8. Convert C pointers to slices with std.mem.span. In the other direction, export fn makes a Zig function callable from C with the C ABI, and extern struct gives C-compatible layout, so Zig can build C libraries or replace C modules incrementally. zig translate-c converts C code to Zig for inspection. Zig can also compile C and C++ source files as part of a build, which lets projects mix languages with one toolchain.

Calling C and exporting to C

@cImport for libc and math, and an exported function.

const std = @import("std");
const c = @cImport({
    @cInclude("stdio.h");
    @cInclude("math.h");
    @cInclude("string.h");
});

// Callable from C as: unsigned long long gst_paise(unsigned long long);
export fn gst_paise(amount: u64) u64 {
    return amount + (amount * 18 + 50) / 100;
}

pub fn main() void {
    _ = c.printf("sqrt(2) = %.4f\n", c.sqrt(2.0));

    const c_name: [*:0]const u8 = "Asha";                  // null-terminated, like a C string
    const len = c.strlen(c_name);
    const slice: []const u8 = std.mem.span(c_name);       // C string to Zig slice
    std.debug.print("strlen={d} slice={s} gst={d}\n", .{ len, slice, gst_paise(10_000) });
}

// zig run main.zig -lc
// or in build.zig: exe.root_module.link_libc = true;  (older versions: exe.linkLibC())

A fluent interpreter at the border

@cImport is an interpreter who reads C headers fluently and translates them on the spot, so Zig code can talk to decades of C libraries without anyone writing a phrasebook (bindings) by hand.

त्वरित जाँच: What does `export fn` do in Zig?

  • Makes a function public within the file
  • Makes the function callable from C with the C ABI and an unmangled name
  • Runs the function at compile time
  • Exports it to JavaScript only
Answer

Makes the function callable from C with the C ABI and an unmangled name — export gives a Zig function C linkage so other languages can call it.