QT DBUS NetworkManager从IP4Config接口获取地址

发布于 2025-01-22 12:20:44 字数 2364 浏览 3 评论 0原文

一段时间以来,我一直在使用QTDBUSNetworkManager,但遇到了问题。我需要访问Wi-Fi设备IP地址,获取它的方法是获取Wi-Fi设备对象,获取其ip4Config属性(QDBUSOBJECTPATH对象),然后获取addressData。问题是,一旦我尝试使用接口属性方法获得地址数据,我的应用程序就会崩溃。

我相信我需要注册一种元类型(我已经为其他类型做了此类型),但似乎无法弄清楚如何解开aa {sv}从属性返回的数据。使用QDBUSVIEWER我可以看到IP地址的数据。

如何从该物业中获取此信息?

这是遇到问题的代码段。看来我可以获得Gateway的QString属性,但是一旦我尝试获得addressData我的进程崩溃(如下所示)。

    cout << wifi_args.size() << endl;
    cout << wifi_args[0].path().toStdString() << endl;
    if (wifi_args.size() > 0) {

        QDBusInterface wifi_device(NM_DBUS_SERVICE, wifi_args[0].path(),
                                   NM_DBUS_INTERFACE_DEVICE,
                                   QDBusConnection::systemBus());

        const auto wifiInterface = wifi_device.property("Interface").toString();
        // auto wifiIPv4 = wifi_device.property("Ip4Address").toInt();
        auto ip4_config_path =
            qdbus_cast<QDBusObjectPath>(wifi_device.property("Ip4Config"));

        cout << "config path = " << ip4_config_path.path().toStdString()
             << endl;

        QDBusInterface wifi_ip4_if(NM_DBUS_SERVICE, ip4_config_path.path(),
                                   NM_DBUS_INTERFACE_IP4_CONFIG,
                                   QDBusConnection::systemBus());

        auto gateway = wifi_ip4_if.property("Gateway").toString();
        auto ipv4 = wifi_ip4_if.property("AddressData");

        // for (auto item : wifiIPv4) {
        //     cout << "Item";
        // }

        cout << "Interface = " << wifiInterface.toStdString() << endl;
        cout << "Gateway   = " << gateway.toStdString() << endl;
        // cout << "Address   = " << int_to_ipv4(wifiIPv4) << endl;
    } else {
        cerr << "ERROR: Multiple wifi devices found!" << endl;
    }

这是运行中的输出:

michael_uman@ThinkPad-X1-Carbon-7th ~/gitroot/UXHUB-development (development)$ ./build-host/app/kylixctl/kylixctl list wifi
1
/org/freedesktop/NetworkManager/Devices/3
config path = /org/freedesktop/NetworkManager/IP4Config/8
Cannot construct placeholder type QDBusRawType
Aborted (core dumped)

I have been using QtDBus and NetworkManager for a while but have run into a problem. I need to access the Wi-Fi devices IP address and the way to obtain it is to get the Wi-Fi device object, get its IP4Config property (a QDbusObjectPath object) and then to get the AddressData. The problem is that as soon as I try to obtain the AddressData using the interfaces property method, my application crashes.

I believe I need to register a meta type (I have done this for other types) but can't seem to figure out how to unpack the aa{sv} data returned from the property. Using qdbusviewer I can see the data for the IP address.

How can I get this information from the property?

Here is a snippet of the code which is encountering the problem. It seems I can get the QString property of Gateway but as soon as I try to get the AddressData my process crashes (as shown below).

    cout << wifi_args.size() << endl;
    cout << wifi_args[0].path().toStdString() << endl;
    if (wifi_args.size() > 0) {

        QDBusInterface wifi_device(NM_DBUS_SERVICE, wifi_args[0].path(),
                                   NM_DBUS_INTERFACE_DEVICE,
                                   QDBusConnection::systemBus());

        const auto wifiInterface = wifi_device.property("Interface").toString();
        // auto wifiIPv4 = wifi_device.property("Ip4Address").toInt();
        auto ip4_config_path =
            qdbus_cast<QDBusObjectPath>(wifi_device.property("Ip4Config"));

        cout << "config path = " << ip4_config_path.path().toStdString()
             << endl;

        QDBusInterface wifi_ip4_if(NM_DBUS_SERVICE, ip4_config_path.path(),
                                   NM_DBUS_INTERFACE_IP4_CONFIG,
                                   QDBusConnection::systemBus());

        auto gateway = wifi_ip4_if.property("Gateway").toString();
        auto ipv4 = wifi_ip4_if.property("AddressData");

        // for (auto item : wifiIPv4) {
        //     cout << "Item";
        // }

        cout << "Interface = " << wifiInterface.toStdString() << endl;
        cout << "Gateway   = " << gateway.toStdString() << endl;
        // cout << "Address   = " << int_to_ipv4(wifiIPv4) << endl;
    } else {
        cerr << "ERROR: Multiple wifi devices found!" << endl;
    }

Here is the output from the run:

michael_uman@ThinkPad-X1-Carbon-7th ~/gitroot/UXHUB-development (development)$ ./build-host/app/kylixctl/kylixctl list wifi
1
/org/freedesktop/NetworkManager/Devices/3
config path = /org/freedesktop/NetworkManager/IP4Config/8
Cannot construct placeholder type QDBusRawType
Aborted (core dumped)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

祁梦 2025-01-29 12:20:44

您可以通过使用org.freedesktop.dbus.properties.get安全地获取有关属性,然后手动demarshall响应,类似于致命的错误,试图使用自定义类型获得DBU属性

// Required operator for demarshalling aa{sv} signature
const QDBusArgument &operator>>(const QDBusArgument &argument, QList<QVariantMap> &varMapList)
{
    argument.beginArray();
    varMapList.clear();

    while(!argument.atEnd()) {
        QVariantMap map;
        argument >> map;
        varMapList.append(map);
    }

    argument.endArray();
    return argument;
}
// Use generic property interface.
QDBusInterface getter(NM_DBUS_SERVICE, wifi_args[0].path(), "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
// Use the Get function to manually access the AddressData property.
auto reply = getter.call("Get", NM_DBUS_INTERFACE_IP4_CONFIG, "AddressData");
// Extract the needed argument from the reply.
auto arg = reply.arguments().first();
// Demarshall the argument into Qt's aa{sv} equivalent.
QList<QVariantMap> list;
arg.value<QDBusVariant>().variant().value<QDBusArgument>() >> list;
// Access the address data.
cout << "Address   = " << list.first()["address"].toString().toStdString();

所需的数据而不会崩溃QT。

You can safely get the property in question by using org.freedesktop.DBus.Properties.Get and then manually demarshall the response, similar to Fatal error when trying to get a DBus property with custom type

// Required operator for demarshalling aa{sv} signature
const QDBusArgument &operator>>(const QDBusArgument &argument, QList<QVariantMap> &varMapList)
{
    argument.beginArray();
    varMapList.clear();

    while(!argument.atEnd()) {
        QVariantMap map;
        argument >> map;
        varMapList.append(map);
    }

    argument.endArray();
    return argument;
}
// Use generic property interface.
QDBusInterface getter(NM_DBUS_SERVICE, wifi_args[0].path(), "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
// Use the Get function to manually access the AddressData property.
auto reply = getter.call("Get", NM_DBUS_INTERFACE_IP4_CONFIG, "AddressData");
// Extract the needed argument from the reply.
auto arg = reply.arguments().first();
// Demarshall the argument into Qt's aa{sv} equivalent.
QList<QVariantMap> list;
arg.value<QDBusVariant>().variant().value<QDBusArgument>() >> list;
// Access the address data.
cout << "Address   = " << list.first()["address"].toString().toStdString();

This should be sufficient to get the required data without crashing Qt.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文