Giter Site home page Giter Site logo

sdroege / gobject-example-rs Goto Github PK

View Code? Open in Web Editor NEW
42.0 7.0 6.0 115 KB

Example for exporting a GObject/C API from Rust

Makefile 3.65% C 13.56% Rust 74.91% JavaScript 2.22% Python 2.32% Vala 3.35%
rust rust-crate gobject gobject-introspection gnome glib gtk

gobject-example-rs's Introduction

Example for exporting a GObject/C API from Rust

This repository contains an example Rust crate that can compile to a C-compatible shared library and that exports a GObject C API.

At the same time the API provided by this crate can be used directly from Rust by statically linking this crate as well as by dynamically linking against the C-compatible library. Both variants provide exactly the same Rust API.

In addition it provides a way to generate GObject-Introspection metadata that allows usage from other languages, like Python and JavaScript.

Implemented Example APIs

General Structure

Each type comes with 3 Rust modules

  • mod.rs: Contains a Rust wrapper of the API. This is basically the same as what gir would autogenerate, and follows the same patterns as the GLib, GTK, etc. bindings.
  • imp.rs: Contains the definition of the types together with the actual private implementation, plus an inline FFI module that exports C-compatible FFI functions.
  • ffi.rs: Contains Rust FFI definitions of the exported C types. This is only used in combination with the bindings cargo feature (see below).

and a C header that is (for now, see issue 6) manually written.

Details

Pending refactoring in issue 10.

Usage

Usage from Rust

The API from the mod.rs can directly be used from Rust code and follows the same patterns as the GLib, GTK, etc. bindings.

There is example usage in the inline tests inside the mod.rs of each type.

Statically linked crate

The crate can be directly added as a dependency in some other projects Cargo.toml and then the API from the individual mod.rs is available.

This statically links the implementation into the application.

Running make check would run tests in this mode.

Dynamically linked C library (bindings feature)

When adding the crate as a dependency and enabling the bindings cargo feature then the actual implementation of all the types is omitted. Instead dynamic linking against the implementation from the C-compatible shared library will happen.

The API is otherwise exactly the same.

Running make check-bindings would run tests in this mode.

Usage from C

Running cargo build will create a C-compatible shared library in target/debug/libgobject_example.so. The corresponding headers for the API can be found in the include directory.

test.c contains some example usage of the API and make run-c compiles and runs this.

Usage from Python

Via gobject-introspection a Ex-0.1.typelib file is created. This can be used by pygobject to expose the API directly to Python.

test.py contains some example usage of the API and make run-python runs this.

Usage from JavaScript/GJS

Via gobject-introspection a Ex-0.1.typelib file is created. This can be used by gjs to expose the API directly to JavaScript. An alternative for node.js would be node-gtk.

test.js contains some example usage of the API and make run-gjs runs this.

Usage from Vala

Via gobject-introspection a Ex-0.1.gir file is created that contains an XML representation of the API. Vala can directly make use of this.

test.vala contains some example usage of the API and make run-vala runs this.

Usage from other languages

The gobject-introspection .gir and .typelib files can be used to autogenerate bindings for dozens of different languages.

gobject-example-rs's People

Contributors

bilelmoussaoui avatar elmarco avatar fsanchezaedo avatar sdroege avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

gobject-example-rs's Issues

can't compile with rust 1.18

the problem below the line has been resolved by installing a newer cargo version and rust compiler.


with

cargo 0.2.0-nightly (efb482d 2015-04-30) (built 2015-04-30)

and

rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)

i receive

failed to parse manifest at `/home/grindhold/_git_archive/gobject-example-rs/Cargo.toml`

Caused by:
  expected a value of type `string` for the key `lib.name`

when entering a random string as name, (as nothing depends on the lib we build, it should not matter, right?), i receive this:

    Updating git repository `https://github.com/gtk-rs/sys`
    Updating git repository `https://github.com/gtk-rs/glib`
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading pkg-config v0.3.9
 Downloading bitflags v0.9.1
 Downloading libc v0.2.30
 Downloading lazy_static v0.2.8
   Compiling lazy_static v0.2.8
   Compiling libc v0.2.30
   Compiling bitflags v0.9.1
   Compiling pkg-config v0.3.9
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-0.2.8/src/nightly_lazy.rs:18:9: 18:14 error: expected one of `extern`, `fn`, `type`, or `unsafe`, found `const`
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/lazy_static-0.2.8/src/nightly_lazy.rs:18     pub const fn new() -> Self {
                                                                                                                 ^~~~~
Build failed, waiting for other jobs to finish...
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-0.9.1/src/lib.rs:219:1: 219:11 error: no_std is experimental
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/bitflags-0.9.1/src/lib.rs:219 #![no_std]
                                                                                              ^~~~~~~~~~
error: aborting due to previous error
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:185:13: 185:21 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:185            .finish()
                                                                                                            ^~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:184:13: 184:42 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:184            .field("stderr", stderr_debug)
                                                                                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:183:13: 183:42 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:183            .field("stdout", stdout_debug)
                                                                                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:182:13: 182:44 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:182            .field("status", &self.0.status)
                                                                                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:181:13: 181:35 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:181         fmt.debug_struct("Output")
                                                                                                            ^~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:196:19: 196:27 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:196                  .finish()
                                                                                                                  ^~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:195:19: 195:30 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:195                  .field(name)
                                                                                                                  ^~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:194:19: 194:48 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:194                 f.debug_tuple("EnvNoPkgConfig")
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:204:19: 204:27 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:204                  .finish()
                                                                                                                  ^~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:203:19: 203:40 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:203                  .field("cause", cause)
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:202:19: 202:44 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:202                  .field("command", command)
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:201:19: 201:42 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:201                 f.debug_struct("Command")
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:210:19: 210:27 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:210                  .finish()
                                                                                                                  ^~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:209:19: 209:59 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:209                  .field("output", &OutputDebugger(output))
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:208:19: 208:44 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:208                  .field("command", command)
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~~~
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:207:19: 207:42 error: use of unstable library feature 'debug_builders': method was just created
/home/grindhold/.cargo/registry/src/github.com-1ecc6299db9ec823/pkg-config-0.3.9/src/lib.rs:207                 f.debug_struct("Failure")
                                                                                                                  ^~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to 16 previous errors
Could not compile `lazy_static`.

Is my setup hopelessly outdated or what am i doing wrong?

Make API less abstract and confusing

What I would suggest is the following

  • Foo becomes Animal
    • Implements Nameable
    • increment() vfunc becomes pet() and returns a Sound (former RString). E.g. cats would "purr"
    • incremented signal becomes made_sound(), see above. This can of course also happen independently of calling
    • name property stays and maps to the Nameable interface
    • Add a new lift() vfunc that either succeeds or returns the (to be written) GError: "too heavy", "too slippery" (e.g. a fish), "hissed", etc
    • Add a new environment read-only property of type Environment (the flags type): "house", "garden", "aquarium", whatever
  • Bar becomes Cat
    • number property would become collar-color of type Color (the enum)
  • Nameable can stay the same, Animals and other things are usually nameable
  • RString becomes Sound (or a better name)
    • Also we'd add accessors for the non-NUL-terminated string plus length without copying
  • SharedRString becomes Name (and is used as part of Nameable). Names are usually used often and immutable
    • Also we'd add accessors for the non-NUL-terminated string plus length without copying

CC @elmarco what do you think? Any suggestions for improvements or changes? :)

typelib won't build

sorry to bother again, but the typelib target won't yield anything useful. Is there any path-stuff i have to set manually?

g-ir-scanner -v --warn-all \
	--namespace Ex --nsversion=0.1 \
	-Iinclude --c-include "ex/ex.h" \
	--library=gobject_example --library-path=target/debug \
	--include=GObject-2.0 -pkg gobject-2.0 \
	--output Ex-0.1.gir \
	include/ex/ex.h include/ex/foo.h include/ex/bar.h include/ex/nameable.h include/ex/rstring.h include/ex/shared-rstring.h 
/usr/bin/libtool: line 2459: printf: write error: Bad file descriptor
g-ir-scanner: link: libtool --mode=link --tag=CC x86_64-linux-gnu-gcc -pthread -o /home/grindhold/_git_archive/gobject-example-rs/tmp-introspect7zjyawul/Ex-0.1 -export-dynamic tmp-introspect7zjyawul/home/grindhold/_git_archive/gobject-example-rs/tmp-introspect7zjyawul/Ex-0.1.o -L. -lgobject_example -Ltarget/debug -lgio-2.0 -lgobject-2.0 -Wl,--export-dynamic -lgmodule-2.0 -pthread -lglib-2.0
libtool: link: x86_64-linux-gnu-gcc -pthread -o /home/grindhold/_git_archive/gobject-example-rs/tmp-introspect7zjyawul/Ex-0.1 tmp-introspect7zjyawul/home/grindhold/_git_archive/gobject-example-rs/tmp-introspect7zjyawul/Ex-0.1.o -Wl,--export-dynamic -pthread -Wl,--export-dynamic  -L. -lgobject_example -Ltarget/debug -lgio-2.0 -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -pthread
/usr/bin/libtool: line 2459: printf: write error: Bad file descriptor
ERROR: can't resolve libraries to shared libraries: gobject_example
Makefile:33: recipe for target 'Ex-0.1.gir' failed
make: *** [Ex-0.1.gir] Error 1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.