The main dbus crate is fairly mature and the features you need should be all there. Breaking changes can still happen, but not often.
- Use
Connection
to connect to the system or session bus. - Use
Message
to send and receive messages. Get and append arguments of all types (including Unix Fd), see the argument guide for details. - Build method dispatching servers using the
tree
module. Standard D-Bus interfaces (introspection, properties, object manager) are supported.
If you have questions or comments that the documentation cannot answer in an easy way, filing an issue with your question is fine. Pull requests that improve the code, documentation, etc, are welcome!
- dbus-codegen installs a binary tool which generates Rust code from D-Bus XML introspection data. The readme contains an introduction to how to use it.
- libdbus-sys contains the raw FFI bindings to libdbus.
- dbus-tokio integrates D-Bus with Tokio. It will be deprecated or rewritten from scratch when Tokio has caught up with
std::future
and async/await.
This example opens a connection to the session bus and asks for a list of all names currently present.
let c = Connection::get_private(BusType::Session)?;
let m = Message::new_method_call("org.freedesktop.DBus", "/", "org.freedesktop.DBus", "ListNames")?;
let r = c.send_with_reply_and_block(m, 2000)?;
let arr: Array<&str, _> = r.get1()?;
for name in arr { println!("{}", name); }
You can try a similar example by running:
cargo run --example client
This example grabs the com.example.dbustest
bus name, registers the /hello
path and adds a method which returns a string.
It then listens for incoming D-Bus events and handles them accordingly.
let c = Connection::get_private(BusType::Session)?;
c.register_name("com.example.dbustest", NameFlag::ReplaceExisting as u32)?;
let f = Factory::new_fn::<()>();
let tree = f.tree(()).add(f.object_path("/hello", ()).introspectable().add(
f.interface("com.example.dbustest", ()).add_m(
f.method("Hello", (), |m| {
let n: &str = m.msg.read1()?;
let s = format!("Hello {}!", n);
Ok(vec!(m.msg.method_return().append1(s)))
}).inarg::<&str,_>("name")
.outarg::<&str,_>("reply")
)
));
tree.set_registered(&c, true)?;
c.add_handler(tree);
loop { c.incoming(1000).next(); }
You can try a similar example (which has more comments) by running:
cargo run --example server
Or a more advanced server example:
cargo run --example adv_server
More examples are available in the examples directory.
Libdbus 1.6 or higher, and latest stable release of Rust. If you run Ubuntu, this translates to Ubuntu 14.04 or later, having the libdbus-1-dev
and pkg-config
packages installed while building, and the libdbus-1-3
package installed while running.
However, if you enable the feature no-string-validation
, you might be able to build and run with older versions of the D-Bus library. This feature skips an extra check that a specific string (e g a Path, ErrorName etc) conforms to the D-Bus specification, which might also make things a tiny bit faster. But - if you do so, and then actually send invalid strings to the D-Bus library, you might get a panic instead of a proper error.
Cross compiling libdbus might be tricky because it binds to a C library, there are some notes here. If you have succeeded, please help out by updating that document.
Apache 2.0 / MIT dual licensed. Any PR you make is assumed to have this license.