2

我正在开发一个在内部使用 Glib 连接到其他模块的库。

这个库有一个用于设置 dbus 连接的初始化方法和一个用于完成所有内部资源(包括 dbus 连接)的终止方法。至少它应该这样做。

但是,在调用 terminate 方法后,我无法再次调用 dbus(当然,在再次调用 dbus 方法之前,我再次调用了 initialize 方法)。

我主要使用 C++(一些用过的库在 C 中)。

这是我的内部 dbus 初始化程序:

#ifdef __cplusplus
extern "C" {
#endif

#include <dbus/dbus-glib.h>
#include <stdio.h>

#define _DBUS_SERVICE       "Removed due to restrictions"
#define _DBUS_PATH      "/"
#define _DBUS_INTERFACE "Removed due to restrictions"

static DBusGConnection * my_dbus_conn = NULL;
static DBusGProxy * my_proxy = NULL;

gboolean dbus_init() {
    GError *error = NULL;
    g_type_init();
    my_dbus_conn = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
    if (my_dbus_conn == NULL) {
        g_printerr("DBUS Connection Error (%s)\n", error->message);
        g_error_free(error);
        return false;
    }
    my_proxy = dbus_g_proxy_new_for_name(my_dbus_conn, _DBUS_SERVICE, _DBUS_PATH, _DBUS_INTERFACE);
    if (my_proxy == NULL) {
        g_printerr("ERROR: DBUS Proxy creation Error (%s)\n", error->message);
        g_error_free(error);
        return false;
    }
    return true;
}

DBusGProxy * dbus_get_proxy() {
    if (my_proxy == NULL) {
        dbus_init();
    }
    return my_proxy;
}

void dbus_term() {
    g_object_unref(G_OBJECT (my_proxy));
    dbus_g_connection_unref(my_dbus_conn);
    my_dbus_conn = NULL;
}

#ifdef __cplusplus
}
#endif

这是我的调用代码:

MY_G_DEBUG("Manager", "Creating Server IPC stub...");
this->m_pDbusServer = get_proxy();

if (this->m_pDbusServer == NULL) {
    return;
}

MY_G_DEBUG("Manager", "CheckPoint 1!");
gboolean success;
GError *gerror = NULL;
char **l_pHelloWorldReply;

success = dbus_server_helloworld(this->m_pDbusServer, "Hello World from Manager", &l_pHelloWorldReply, &gerror);

MY_G_DEBUG("Manager", "CheckPoint 2!");

if (success == FALSE) {
    MY_G_DEBUG("Manager", "CheckPoint 3!");
    if (gerror == NULL) {
        MY_G_DEBUG("Manager", "CRITICAL: Hello World call Failed (error not set)");
    } else {
        MY_G_DEBUG("Manager", "CRITICAL: Hello World call Failed (%s)", gerror->message);
        g_error_free(gerror);
        gerror = NULL;
    }
    return;
} else {
    MY_G_DEBUG("Manager", "CheckPoint 4!");
    for (guint ii = 0; l_pHelloWorldReply[ii] != NULL; ii++) {
        MY_G_DEBUG("Manager", "Hello World response %d: %s", ii, l_pHelloWorldReply[ii]);
    }
}

MY_G_DEBUG("Manager", "CheckPoint 5!");

这是日志记录输出:

(process:24498): Manager-DEBUG: Checkpoint: 1!
(process:24498): Manager-DEBUG: Checkpoint: 2!
(process:24498): Manager-DEBUG: Checkpoint: 3!
(process:24498): Manager-DEBUG: CRITICAL: Hello World call Failed (error not set)

每次调用 dbus_term 函数时都会收到一条错误消息,但是我无法修复它。

(process:24498): GLib-GObject-WARNING **: invalid uninstantiatable type `<invalid>' in cast to `GObject'
(process:24498): GLib-GObject-CRITICAL **: g_object_unref: assertion `G_IS_OBJECT (object)' failed

我第一次尝试调用方法时,一切正常……我坚信这是由 dbus_term 问题引起的。

有谁知道为什么会这样?

非常感谢。

4

2 回答 2

1

It is a bug to drop the last reference to a dbus connection that is still open. One of the problems with the bindings that you are using is that it is difficult to know when the connection actually closes. It is somewhat unsatisfying, but it has been my practice to leave one reference around on connections to a well known bus like the session bus.

于 2011-03-17T07:50:44.527 回答
-2

不要在新代码中使用 dbus-glib,而是使用 GDBus。

GDBus 是 glib 2.26 中的新 dbus api。与 dbus-glib 相比,它的优势包括使用 GIO 异步模式(GAsync*、GCancellable)、将 GVariant 用于变体类型和更好的线程支持。

有关迁移到 GDBus 的信息,请参阅 http://library.gnome.org/devel/gio/2.28/ch29.html

于 2011-03-17T08:40:16.337 回答