How do I obtain GDBus interface name with Giomm?

242 views Asked by At

I am trying to detect added Bluetooth devices/adapters using Bluez D-Bus API and GDBus. However, I am unable to check the name of the added D-Bus interface.

I already tried accessing the interface name using the underlying GDBusInterfaceInfo C object, but calling get_info() on a Gio::DBus::Interface either causes a segmentation fault or returns a null pointer.

In addition, calling get_interface("org.bluez.Adapter1") on a Gio::DBUS::Object prints this warning:

** (process:60136): WARNING **: 11:11:58.443: Glib::wrap_auto_interface(): The C++ instance (N3Gio4DBus5ProxyE) does not dynamic_cast to the interface.

Here is my code. I compiled it with: g++ dbus.cpp `pkg-config --cflags --libs glibmm-2.4 giomm-2.4` -g and my glibmm version is glibmm 2.66.4-1.

#include <glibmm.h>
#include <giomm.h>

void on_object_added(const Glib::RefPtr<Gio::DBus::Object>& o)
{
    for (auto iface : o->get_interfaces())
    {
        auto info = iface->get_info(); // Causes Segmentation fault.
        if (!info)
        {
            std::cout << "Null InterfaceInfo\n";
        }
    }
}

int main()
{
    Gio::init();

    auto loop = Glib::MainLoop::create();
    auto objman = Gio::DBus::ObjectManagerClient::create_for_bus_sync(
        Gio::DBus::BUS_TYPE_SYSTEM, "org.bluez", "/");

    objman->signal_object_added().connect(sigc::ptr_fun(&on_object_added));

    for (const auto& o : objman->get_objects())
    {
        std::cout << o->get_object_path() << '\n';

        // The next line prints:
        // ** (process:60136): WARNING **: 11:11:58.443: Glib::wrap_auto_interface(): The C++ instance (N3Gio4DBus5ProxyE) does not dynamic_cast to the interface.
        auto adapter = o->get_interface("org.bluez.Adapter1");

        for (const auto& iface : o->get_interfaces())
        {
            // iface is not a GDBus Proxy instance,
            // but a PN3Gio4DBus9InterfaceE.
            std::cout << " " << typeid(iface.operator->()).name() << '\n';
        }

        std::cout << '\n';
    }

    loop->run();
}

What am I doing wrong? How can I see the name of an interface when I am not dealing with a GDBusProxy instance? Is it possible to obtain a GDBusProxy instance using GDBusObjectManagerClient?

I couldn't find any examples on how to do this. It seems like Giomm GDBus examples and support are in short supply.

1

There are 1 answers

0
that person On

Try:

auto proxy = std::dynamic_pointer_cast<Gio::DBus::Proxy>(iface);
std::cout << ' ' << proxy->get_interface_name() << '\n';

This works for me using glibmm-2.68.

The documentation for Gio::DBus::Interface shows that Gio::DBus::Interface is a superclass of Gio::DBus::Proxy, and indeed it seems that all the Gio::DBus::Interface instances in your provided code are also Gio::DBus::Proxy instances.