Is it possible to expose a C global variable through Zig?

I’m working on a test case that involves marshaling a function call from JavaScript into C. For this reason I’m exposing certain C functions from stdio.h as public decls:

const c = @cImport({
    @cInclude("stdio.h");
});

pub const stdin = c.stdin;
pub const stdout = c.stdout;
pub const stderr = c.stderr;
pub const fwrite = c.fwrite;
pub const puts = c.puts;

The code above doesn’t work, since c.stdin and co aren’t comptime known. Is it possible to expose these C variables so that they’d be treated as though they’re variables of the Zig module?

I have the following as a workaround for now:

pub fn stream(num: u8) ?*c.FILE {
    return switch (num) {
        0 => c.stdin,
        1 => c.stdout,
        2 => c.stderr,
        else => null,
    };
}

You’ve probably already tried this, but I’m curious if a function that returns an instance pointer could be helpful. Something like foo* get_global_foo()?

I got it to work using extern:

pub extern var stdin: [*c]c.FILE;
pub extern var stdout: [*c]c.FILE;
pub extern var stderr: [*c]c.FILE;
2 Likes