Generate Rust bindings for gtk-layer-shell with gir

Hi,
I am trying to generate bindings for gtk-layer-shell with a provided gir file and followed the tutorial but I have a few questions. The code is available at https://github.com/grelltrier/gtk-layer-shell-gir

1: I got a bunch of errors when generating the Rust wrapper because of missing macro definitions. When I searched on Github, it seemed as if people just implement those macros themselves and they all looked the same so I just copied them and added the following to my lib.rs :

/// Asserts that this is the main thread and either `gdk::init` or `gtk::init` has been called.
macro_rules! assert_initialized_main_thread {
    () => {
        if !::gtk::is_initialized_main_thread() {
            if ::gtk::is_initialized() {
                panic!("GTK may only be used from the main thread.");
            } else {
                panic!("GTK has not been initialized. Call `gtk::init` first.");
            }
        }
    };
}

/// No-op.
macro_rules! skip_assert_initialized {
    () => {};
}

Is that a good idea or should I do something else?

2: When I try building the generated Rust wrapper I get two errors complaining about unresolved imports for each of the generated enums because the enums are defined in enums.rs but functions.rs tries importing them via

use Edge;
use Layer;

This fails but if I replace it with use super::enums::*; I no longer get any errors. Since I can read, I know you are not supposed to edit the generated files :stuck_out_tongue:
How can I generate correct code?

3: Additionally to enums.rs and function.rs a window.rs was generated. I don’t understand this file at all tbh. I don’t get why it is there/needed since I thought I told gir not to worry about Gtk.Window and I do not understand its code. Aside from that there is also a lot of code commented out. The tutorial said to add the types that follow the /Ignored/ to the Gir.toml under manual= []
I tried adding them but nothing changes. In case you’ll have a look at my repository, right now those types are commented out since they did not change anything anyways.

4: Since one of the needed types is Gdk.Monitor I added gdk to the dependencies in the cargo.toml and added features= [“v3_22”]. Then I added extern crate gdk;
Is that the proper way to do this?

All in all I am very impressed by gir and the generated code. Looks really nice and its a lot easier than writing it myself.
Thank you for taking the time to help :slight_smile:

I guess we forgot to add a few things into the tutorial, so some updates will be required! I’ll answer your questions, but please open issues on the repository:

  1. … Is that a good idea or should I do something else?

No it’s good.

  1. … How can I generate correct code?

The code is actually generated correctly, but you’re supposed to reexport all types (including enums) in the lib.rs file.

There are two ways to ignore items: in ignore = [...] field, or declaring the type on its own and adding ignore = true. But if you still want the bindings to know that the type is available, you have to add it into the manual = [...] field.

It depends: if you always want to have this feature enabled, then yes, it’s the best way to do it. If it’s optional though, you’ll want to declare a feature on your crate which will also enable the gdk’s one:

[features]
my_feature_name = ["gdk/v3_22"]

So when you enable my_feature_name, you’ll also enable the feature v3_22 in gdk.

3 Likes

Thank you for your reply, I opened the following issues: #957 #958 #959 #960
(sorry, new users like me can only add two links -,-)

1 and 4 have been solved, thanks :slight_smile:

3 is also solved. I didn’t understand why I even needed a window.rs implementing a whole bunch of stuff for Gtk.Window. Turns out I don’t. It was just a remainder from running gir before I guess and it didn’t get deleted when re-running gir which makes sense. I assume that is also the reason why adding all those types to manual = [ ] did not make any difference to the functions getting un-commented. Gir never generated a new window.rs so it was not replaced. After I deleted all files in the auto folder an ran gir again it was not created again.

Regarding point 2 I am afraid, I need more hand-holding. You said “you’re supposed to reexport all types”. Are you referring to adding
pub use self::auto::functions::;
pub use auto::
;
mod auto;
to the lib.rs? I had done that but the error remains. I also added
pub use self::Edge;
pub use self::Layer;
to lib.rs but that also did not help. I assume it is because the functions in functions.rs are global functions and they rely on enums from the enums.rs file. The enums.rs is private but in mod.rs in the auto folder/module it says:
mod enums;
pub use self::enums::Edge;
pub use self::enums::Layer;
pub mod functions;
In functions.rs it says
use Edge;
use Layer;

Could you please point me to the correct direction regarding this last issue?

Rust-2018 changed some things with use paths. You may need to remove the edition = "2018" line from your Cargo.toml.

1 Like

The gtk-rs code generator gir does not support Rust 2018 yet, see this issue. You need to configure 2015 edition (or nothing at all) in your Cargo.toml of the bindings or otherwise it won’t work well.

Using the generated bindings from Rust 2018 edition is no problem though.

1 Like

Awesome, all my problems have been resolved! Thank you!
Unfortunately I can only mark one answer as the solution so I marked @GuillaumeGomez answer as the solution since he gave me solutions for most of my questions.

In case anybody dares to try out my wrapper, its on crates.io now :slight_smile:

1 Like

Usually the unsafe FFI bindings are in a crate named whatever-sys while the whatever crate contains safe wrappers on top of the unsafe FFI bindings (compare for example gtk and gtk-sys).

You can also use the gir tool to generate safe wrappers around the unsafe FFI bindings (to some degree, depending on how well the C library follows the GObject-Introspection principles).

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