Creating opaque extern struct for C structs

Say I have a C struct which’s size is 24 and alignment is 8, would something like this work as a opaque struct if I want to pass it to C functions as void* or *anyopaque and the C function will cast back to the orignal type to manipulate it’s values:

const OpaqueInZig = extern struct {
    __opaque: [24]u8 align(8) =  std.mem.zeroes([24]u8),
};

Yes, you can directly pass a pointer to OpaqueInZig as *anyopaque.

const std = @import("std");

const OpaqueInZig = extern struct {
    __opaque: [24]u8 align(8) = std.mem.zeroes([24]u8),
};

pub fn main() !void {
    std.debug.print("size={d}\nalign={d}\n", .{
        @sizeOf(OpaqueInZig),
        @alignOf(OpaqueInZig),
    });
}

Tried the program with various 32 and 64 targets and it always returns:

❯ zig run test.zig
size=24
align=8
2 Likes

You can also make two structs:

const OpaqueImpl = extern struct {
    foo: Bar
};

const Opaque = opaque {
    fn getFoo(o: *Opaque) Bar {
        return @as(*OpaqueImpl, @ptrCast(o)).foo;
    }
};
1 Like