Using glib-rs in reverse

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.

1 Like

If good, I don’t know, but I made an example project like this a while ago. You can find it here: GitHub - sdroege/gobject-example-rs: Example for exporting a GObject/C API from Rust

I should probably clean that up a bit and update with the latest idioms :slight_smile: 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.

Thanks for the reply!

GitHub - sdroege/gobject-example-rs: Example for exporting a GObject/C API from Rust

That is useful yep, though it doesn’t look like it has any GError usage: https://github.com/sdroege/gobject-example-rs/search?q=GError

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()

1 Like

Random thought: maybe alias it to glib::CUtf8Str ?

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.