const std = @import("std"); const fmt = std.fmt; const testing = std.testing; const print = std.debug.print; const GPA = std.heap.GeneralPurposeAllocator(.{ .safety = true }); pub const Context = struct { const Self = @This(); rundir: [:0]u8, gpa: GPA, pub fn init(gpa: *GPA) !Self { var rundir = try gpa.allocator().dupeZ(u8, "/tmp/libipc-run/"); return Self{ .rundir = rundir, .gpa = gpa.* }; } pub fn deinit(self: *Self) void { self.gpa.allocator().free(self.rundir); } }; export fn ipc_context_init() callconv(.C) ?*anyopaque { std.log.err("Let's use GPA!", .{}); var gpa = GPA{}; var new_context = gpa.allocator().create(Context) catch return null; new_context.* = Context.init(&gpa) catch return null; return new_context; } export fn ipc_context_deinit(opaque_ctx: *anyopaque) callconv(.C) void { var ctx = @ptrCast(*Context, @alignCast(@alignOf(Context), opaque_ctx)); ctx.deinit(); var gpa = ctx.gpa; // save the gpa before destroying ctx std.log.err("Let's destroy Context!", .{}); gpa.allocator().destroy(ctx); _ = gpa.deinit(); // now deinit the gpa } test "context_init_deinit" { const ctx = ipc_context_init(); try std.testing.expect(ctx != null); ipc_context_deinit(ctx.?); }