首页 > 解决方案 > 如何正确管理 g_dbus_interface_get_object() 返回的引用

问题描述

我有一个应用程序,我在其中使用 UDisk 来处理一些驱动器和分区。在我的应用程序中,我有一个指向 a 的指针UDisksDrive,我需要将其转换为UDisksObject以后可以访问其他接口的指针。我不清楚我应该取消引用哪些对象以及何时取消引用。在一个功能中,我目前正在执行以下操作:

    UDisksDrive* drive = udisks_client_get_drive_for_block(client, block);
    if(drive == NULL) {
        g_object_unref(block);
        return NULL;
    }

    UDisksObject* driveObject = (UDisksObject*) g_dbus_interface_get_object(G_DBUS_INTERFACE(drive));
    g_object_unref(drive);
    return driveObject;

但我不知道这是否正确。它有效,但我知道这可能并不一定意味着什么。gdbus 文档的g_dbus_interface_get_object()读取就像我不应该driveObject在接收函数完成时取消引用返回的变量,但我不确定。我觉得我应该block在函数返回之前取消引用,但我不知道为什么我不这样做。这是一个我只有时间在这里和那里工作的项目,我觉得也许我已经尝试过了,但它导致了崩溃或异常。

我的大部分其他涉及 UDisk 的代码都非常简单。我_get_的东西,使用它,并取消引用它。正是这些涉及界面交换的东西,我有点模糊。

标签: linuxmemory-managementgdbusudisks

解决方案


是时候思考、研究和在 IRC 上进行的简短交谈得出以下结论:

是的,我绝对需要block在函数返回之前释放(取消引用)。此外,g_dbus_interface_get_object()这种情况下的功能是否错误。因为我不关心drive并且只想返回driveObject,所以我需要使用g_dbus_interface_dup_object()它,它允许返回的指针拥有它自己的引用。这使得调用者driveObject在完成后可以安全地释放它。所以更新后的代码片段如下所示:

    UDisksDrive* drive = udisks_client_get_drive_for_block(client, block);
    if(drive == NULL) {
        g_object_unref(blockObject);
        g_object_unref(block);
        return NULL;
    }

    UDisksObject* driveObject = (UDisksObject*) g_dbus_interface_dup_object(G_DBUS_INTERFACE(drive));
    g_object_unref(block);
    g_object_unref(drive);
    g_object_unref(blockObject);

    return driveObject;

推荐阅读