gi-rust / grust Goto Github PK
View Code? Open in Web Editor NEWGObject introspection bindings for the Rust programming language
License: GNU Lesser General Public License v2.1
GObject introspection bindings for the Rust programming language
License: GNU Lesser General Public License v2.1
We need to figure out the semantics of passing safe callbacks from Rust to GObject:
The cross-thread call paths are an albatross for code size, performance, and they use a sentinel thread with a statically unpredictable failure mode in case of a deadlock. Reducing to on-stack FFI calls with single-task ownership for all Rust boxes of a GObject seems like a more practical approach.
The battle plan after an IRC discussion with @strcat:
Option<Object<T>>
,Rust's powerful macro system can greatly improve readability for the generated code and facilitate creation of bindings by hand, should such a need arise.
Ideally, declarations of binding types for GObject could look like this:
gobject_decl! {
class FileInputStream : InputStream {
type_fn g_file_input_stream_get_type();
}
sync class Cancellable {
type_fn g_cancellable_get_type();
}
interface AsyncResult {
type_fn g_async_result_get_type();
}
}
The type structs and much of the boilerplate traits for type ID, casting and wrapping can be generated from such compact descriptions.
Another area to benefit from macroization is transformation of parameters and output values between Rust and C.
Removing the move
in this line causes the test to crash when compiled with rustc 1.0.0-alpha.
Curiously, doing the same to the other tests does not produce any crashes.
Find out if the problem is in unsafe code in Grust, or is it a compiler bug.
GObject-based objects are not generally thread-safe, so it may not be safe to call GObject methods directly from different concurrent tasks. If we freely allow cloning and sending wrapped GObject references in safe Rust code, we should forward all GObject calls through a dedicated long-running task. grust::init
could be the place where this task is started.
There are libraries, most notably Gtk+ and GDK,that expect all their usage to occur within a single thread, except for some thread-safe functions and objects. To bind these libraries safely, it seems necessary to generate code differently, passing a reference to a non-sendable global context object to every function that is not designated thread-safe or does not use some non-sendable objects from the same library.
Typically, such libraries have one or more initialization functions of which one must be called before any other use of the library can occur. These can be represented in Rust by functions returning the library context value.
Hi! First I'd like to say I'm really happy that this project is in progress. I think it's going to be really cool when bindings to cool libraries like gtk, and libpeas can be automatically generated. Second, I'd like to report an issue. This project does not work with out of tree builds. For example, I moved to a different directory builds/grust from the directory projects/grust, and ran the command ../../projects/grust/configure, and though the project was succesfully configured the Makefile failed to build the project properly. I'd be wiling to help out on solving this issue as I have experience working with autotools but I am unfamiliar with the source of this project.
A solution is needed for dynamic down- and side-casting between traits representing GObject interfaces.
It should be as idiomatic Rust as possible, and invoke GObject dynamic cast checks.
A smaller goal than #1 is to implement the generation mode to produce just the sys crates, to stop manually editing the currently maintained -sys crates and enable generation of many more linkage crates from GIR.
A list of existing -sys crates that could benefit from this:
We need a GIR-to-Rust code generator to automate most of the dirty work.
There are cases when an object can be sent to another thread as long as no other references to it exist in safe code.
Add a sendable reference type NewRef
with the following features:
Deref
s to the objectSend
Clone
park()
, promotes a NewRef
into Ref
, effectively parking the object in the calling thread.See some rationale in a comment on the GObject-introspection bug regarding thread-safety annotations.
The Rust reference says it is undefined behavior to cross the FFI boundary while unwinding.
We need some reliable way to prevent unwinding in callbacks.
We need to find a way to represent GLib errors in Rust that is: 1) as idiomatic Rust as possible; 2) able to provide all information of a GError value.
The current prototype code in fauxgen simply takes the message out of a GError to pass to fail!(), which is lossy and provides no way to match and handle recoverable errors.
There is talk on the mailing list about "conditions" as a more versatile mechanism of handling errors, but none of that can be found in the documentation yet.
If conditions do not become available, my reserve idea is to have an ErrorContext trait which can be used to create a temporary object encapsulating a mutable GError pointer for each call site, pass a pointer to the pointer to the C function and call the desired error handling behavior from the temporary's destructor. Different implementations of ErrorContext can ignore errors, fail on them, or do something more sensible depending on the error data. Usage of built-in error handling contexts can be facilitated by helper functions:
grust::fail_on_errors(|err_ctx|, {
obj1.throwing_method1(err_ctx.get());
obj2.throwing_method2(err_ctx.get());
});
Consider passing the async callback closures (FnOnce
) in boxes.
For performance it's likely better if the closure is constructed boxed at the call site.
My attempt to implement this has run into an ICE which looks to be rust-lang/rust#20676.
The code needs to be updated for Rust 0.9.
Should address #10 while I'm at it.
As GCancellable is a mechanism for thread-safe task cancellation, we should have a sendable wrapper for it.
There are GLib types: GVariantBuilder
, GVariantDict
, and GVariantIter
, that can be heap-allocated and then refcounted, or be created on stack which naturally does not allow refcounting.
Bindings for each of these would likely require three different types:
Drop
;Refcount
to represent heap-allocated structures;AsRef
-style conversion from the two types described above.Should package for, and build with Cargo.
Also verify what is needed to provide Cargo infrastructure for generated crates.
Without union support in Rust FFI (rust-lang/rust#5492), there is no easy way to represent GValue and other types.
I like the idea of explicit Ref
smart pointer more than gtk-rs approach. I think it is better because:
When reading the code, you immediately see that it is just a reference, and it's obvious that .clone()
will only create a new reference
It seems that GObject subclassing would be easier this way (compared to current gtk-rs)
However, I see that there has been no commits since 2018. Why? Are there any fundamental issues in this project that can't be resolved?
The documentation says:
It is not permissible to use [the
GVariantBuilder
instance] in any way after this call
except for reference counting operations (in the case of a
heap-allocatedGVariantBuilder
or by reinitialising it with
g_variant_builder_init()
(in the case of stack-allocated).
In the bindings, this may mean:
GVariantBuilder
as a by-value parameter (likely self
). It's interesting to support the stack-allocated case as well, so the method may need to be generic over some trait covering both cases.grust::refcount::Ref
would not work safely, as we need the reference to be unique by the time this call is made, or somehow drop all references immediately afterwards.Same applies to g_variant_dict_end()
.
We are likely to need more metadata on the types and functions than what GObject-introspection currently provides.
For #13 and other similar cases, we need a thread safety annotation. I have filed a bug on GObject-introspection, but pending any action on that (and I'm not holding my breath), an in-project solution is needed to augment the GIR data with thread-safety attributes.
Some types and methods need to be blacklisted. In Glib and GObject, we don't want bindings for types that will be supported intrinsically by Grust.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.