|
| 1 | +# Example for exporting a GObject/C API from Rust |
| 2 | + |
| 3 | +This repository contains an example [Rust](https://www.rust-lang.org/) crate |
| 4 | +that can compile to a C-compatible shared library and that exports a |
| 5 | +[GObject](https://developer.gnome.org/gobject/stable) C API. |
| 6 | + |
| 7 | +At the same time the API provided by this crate can be used directly from Rust |
| 8 | +by statically linking this crate as well as by dynamically linking against the |
| 9 | +C-compatible library. Both variants provide exactly the same Rust API. |
| 10 | + |
| 11 | +In addition it provides a way to generate [GObject-Introspection](https://gitlab.gnome.org/GNOME/gobject-introspection/) |
| 12 | +metadata that allows usage from other languages, like [Python](https://gitlab.gnome.org/GNOME/pygobject/) and |
| 13 | +[JavaScript](https://gitlab.gnome.org/GNOME/gjs). |
| 14 | + |
| 15 | +## Implemented Example APIs |
| 16 | + |
| 17 | +### General Structure |
| 18 | + |
| 19 | +Each type comes with 3 Rust modules |
| 20 | + |
| 21 | + * `mod.rs`: Contains a Rust wrapper of the API. This is basically the same |
| 22 | + as what [gir](https://github.com/gtk-rs/gir) would autogenerate, and |
| 23 | + follows the same patterns as the GLib, GTK, etc. bindings. |
| 24 | + * `imp.rs`: Contains the definition of the types together with the actual |
| 25 | + private implementation, plus an inline FFI module that exports |
| 26 | + C-compatible FFI functions. |
| 27 | + * `ffi.rs`: Contains Rust FFI definitions of the exported C types. This is |
| 28 | + only used in combination with the `bindings` cargo feature (see below). |
| 29 | + |
| 30 | +and a C header that is (for now, see [issue 6](https://github.com/sdroege/gobject-example-rs/pull/6)) |
| 31 | +manually written. |
| 32 | + |
| 33 | +### Details |
| 34 | + |
| 35 | +Pending refactoring in [issue 10](https://github.com/sdroege/gobject-example-rs/issues/10). |
| 36 | + |
| 37 | +## Usage |
| 38 | + |
| 39 | +### Usage from Rust |
| 40 | + |
| 41 | +The API from the `mod.rs` can directly be used from Rust code and follows the |
| 42 | +same patterns as the GLib, GTK, etc. bindings. |
| 43 | + |
| 44 | +There is example usage in the inline tests inside the `mod.rs` of each type. |
| 45 | + |
| 46 | +#### Statically linked crate |
| 47 | + |
| 48 | +The crate can be directly added as a dependency in some other projects |
| 49 | +`Cargo.toml` and then the API from the individual `mod.rs` is available. |
| 50 | + |
| 51 | +This statically links the implementation into the application. |
| 52 | + |
| 53 | +Running `make check` would run tests in this mode. |
| 54 | + |
| 55 | +#### Dynamically linked C library (`bindings` feature) |
| 56 | + |
| 57 | +When adding the crate as a dependency and enabling the `bindings` cargo |
| 58 | +feature then the actual implementation of all the types is omitted. Instead |
| 59 | +dynamic linking against the implementation from the C-compatible shared |
| 60 | +library will happen. |
| 61 | + |
| 62 | +The API is otherwise exactly the same. |
| 63 | + |
| 64 | +Running `make check-bindings` would run tests in this mode. |
| 65 | + |
| 66 | +### Usage from C |
| 67 | + |
| 68 | +Running `cargo build` will create a C-compatible shared library in |
| 69 | +`target/debug/libgobject_example.so`. The corresponding headers for the API |
| 70 | +can be found in the `include` directory. |
| 71 | + |
| 72 | +`test.c` contains some example usage of the API and `make run-c` compiles and |
| 73 | +runs this. |
| 74 | + |
| 75 | +### Usage from Python |
| 76 | + |
| 77 | +Via [gobject-introspection](https://gitlab.gnome.org/GNOME/gobject-introspection/) |
| 78 | +a `Ex-0.1.typelib` file is created. This can be used by [pygobject](https://gitlab.gnome.org/GNOME/pygobject/) |
| 79 | +to expose the API directly to Python. |
| 80 | + |
| 81 | +`test.py` contains some example usage of the API and `make run-python` runs this. |
| 82 | + |
| 83 | +### Usage from JavaScript/GJS |
| 84 | + |
| 85 | +Via [gobject-introspection](https://gitlab.gnome.org/GNOME/gobject-introspection/) |
| 86 | +a `Ex-0.1.typelib` file is created. This can be used by [gjs](https://gitlab.gnome.org/GNOME/gjs) |
| 87 | +to expose the API directly to JavaScript. An alternative for [node.js](https://nodejs.org) would |
| 88 | +be [node-gtk](https://github.com/romgrk/node-gtk). |
| 89 | + |
| 90 | +`test.js` contains some example usage of the API and `make run-gjs` runs this. |
| 91 | + |
| 92 | +### Usage from Vala |
| 93 | + |
| 94 | +Via [gobject-introspection](https://gitlab.gnome.org/GNOME/gobject-introspection/) |
| 95 | +a `Ex-0.1.gir` file is created that contains an XML representation of the API. |
| 96 | +[Vala](https://wiki.gnome.org/Projects/Vala) can directly make use of this. |
| 97 | + |
| 98 | +`test.vala` contains some example usage of the API and `make run-vala` runs this. |
| 99 | + |
| 100 | +### Usage from other languages |
| 101 | + |
| 102 | +The [gobject-introspection](https://gitlab.gnome.org/GNOME/gobject-introspection/) |
| 103 | +`.gir` and `.typelib` files can be used to autogenerate bindings for dozens of |
| 104 | +different languages. |
| 105 | + |
0 commit comments