Hello,
Objective: To build a Zig wrapper around a C-lib. This C-lib has callbacks that can be registered and fired from the C-based code. However, I’d like end-users of the Zig wrapper to not have to concern themselves with the callconv(.C) callbacks and just write Zig callbacks. Internally in my Zig code, it would somehow register true C-ABI callbacks and then call the end-user’s “nicer” Zig callbacks where in some cases the params are different, or cleaned up.
There was an older question I stumbled upon that has a great answer on how to wire up a C callback, which then later calls some Zig code. In the original post, the user needed to call their Zig function which was declared on a method so they needed access to the self parameter.
Here’s the original post: How to wrap a Zig function to be called from C?
My question is related: I’d like to accomplish the same thing but in my case the C callback in a third-party lib, doesn’t have an opaque void*
extra parameter that I can utilize to pass additional context.
Without going down the rabbit hole of global variables or something in static memory am I totally out of luck here? (The c-lib does do some internal multi-threading so global or static memory is likely a bad idea anyway)
I can’t seem to come up with any “closure” based solution because the C callback ultimately has no way of referencing additional context.
For reference here is what the C lib callback looks like and its purpose is for logging. It will be called from C code when I register a user-provided callback. But I want the user of this library to not have to write any callconv(.C) callbacks and write Zig callbacks so I’m trying to get the C callback to dispatch to the Zig callback. I am trying to provide a Zig lib that wraps the C in a more idiomatic style of code.
const ConfLogCallbackCABI = *const fn (c_int, [*c]const u8, [*c]const u8) callconv(.C) void;
First arg is just a integer log level, 2nd is a string which would be like a log class, third is the log message.
I’m aware of Zig’s limitations of not having first class support of true closures because Zig must not have any hidden allocations. I just don’t know if I can do what I want to do or if the user must define their callbacks in the C calling convention if there is no way around this.