In https://github.com/coreos/rpm-ostree/ we’re using the glib crate in both its normal case (call C from Rust) as well as the “reverse” case of having an API primarily implemented in Rust that is called from C.
Two questions:
First, I know of libsrvg as one example of this - are there other good examples of codebases doing this?
(FWIW I like this pattern I made up of having a mod ffi sub-module, a bit like the mod tests pattern)
I notice for example both librsvg and rpm-ostree carry code to convert a Result back into GError (librsvg gerror code and rpm-ostree gerror code - feels like it’d make sense to try to have this in glib-rs right?
And a more specific question: is there an API in glib-rs like this code I just removed? In particular in some hot paths I’d like to avoid UTF-8 validation and the malloc/memcpy by converting to String.
I should probably clean that up a bit and update with the latest idioms librsvg is definitely a better place to look at currently.
Apart from that there’s gst-plugins-rs which provides various GStreamer plugins that can be used from C or other languages, but the C API it provides is in terms of the existing GStreamer/GObject C API and it does not provide any C API by itself, so probably not exactly what you’re looking for either.
Personally I think the pattern in librsvg is a good example of how you can do it and that’s how I would also do it in other projects. GLib-related or not. You’d have some ffi or capi module that exposes the C API, and everything else organized like a normal Rust crate. That’s also what you find with most crates using cargo-c for providing a C library (rav1e, lewton, ebur128, etc.).
There isn’t directly but inside the gtk-rs/gstreamer-rs crates there are various direct uses of std::ffi::CStr for avoiding the malloc/memcpy if it’s safe to do. And you can get something close to this via glib::GString::from_glib_borrow(), which is used e.g. for signal handlers or virtual methods to not have to do copies of string arguments.
I guess none of the GStreamer APIs are using GError?
Ah…I think previously I thought GString was a binding for the glib string and kind of skimmed over it but indeed, I think using that borrow is exactly what I want, thanks!
This might be what you’re looking for. That’s for an interface virtual method, but would basically look the same for any other C function you’d expose.
Yeah it’s a bit confusing… glib::String is GString, glib::GString is a C string that might be allocated by g_malloc()…