Hey, I'm new (hence the beginners channel) and I've been trying my hand a making at platform in Zig.
A part of this, I wanted to make a event queue with a callback system, and I have run into an issue.
This is a minimal example based on https://github.com/lukewilliamboswell/roc-platform-template-zig/
I have a platform function (callback_abi mapped to Callback.callback!) call a roc function like so (this is how it should be called from what little I can find on the matter)
fn callback_abi(callback: abi.RocErasedCallable) callconv(.c) void {
const payload = abi.rocErasedCallablePayloadPtr(callback);
const capture = abi.rocErasedCallableCapturePtr(callback);
// No arguments or return
// fn (host: *RocHost, ret: ?*anyopaque, args: ?*const anyopaque, capture: ?*anyoapque) void
payload.callable_fn_ptr(g_roc_host.?, null, null, capture);
}
comptime {
@export(&callback_abi, .{ .name = "hosted_callback", .visibility = .hidden });
}
And then that callback call another native function
init! : {} => {}
init! = |{}| {
Callback.callback!(
Box.box(
|{}| {
dbg "Arrived"
Stderr.line!("We don't get here :(")
},
),
)
}
The callback correctly runs at first (debug printing "arrived")
but crashes before getting to the platform Stderr.line! implementation
Without this Stderr.line!, it works correctly and returns from the roc function, but any platform call here I try fails before getting to the platform.
(Stderr.line! also separately works outside of the callback)
1) Is there any ideas on what I am doing wrong? (calling the function wrong or something?)
2) Are there any more resources for making platforms like this? (the ones I have found are mostly pre-rewrite and I wasn't sure how helpful they would be)
Last updated: Jul 23 2026 at 13:15 UTC