2017-04-22 60 views
1

我使用的是低層次的DBus C庫implimenting的StatusNotifierWatcher服務消失觀看。該StatusNotifierWatcher規範要求觀察者可以知道,當「A StatusNotifierItem實例已經從總線消失」因此,它可以發送StatusNotifierItemUnregistered信號。的DBus:當名字從總線

一個例子執行力度:

#include <stdio.h> 
#include <stdlib.h> 
#include <dbus/dbus.h> 

DBusConnection *conn = NULL; 

void item_unregistered_signal(const char *name) { 
    DBusMessage *signal = dbus_message_new_signal(
      "/org/freedesktop/StatusNotifierWatcher", 
      "org.freedesktop.StatusNotifierWatcher", 
      "StatusNotifierItemUnregistered"); 
    dbus_message_append_args(signal, 
      DBUS_TYPE_STRING, &name, 
      DBUS_TYPE_INVALID); 
    dbus_connection_send(conn, signal, NULL); 
    dbus_message_unref(signal); 
} 

void watch_name(const char *name, void(*cb)(const char *)) { 
    // Not sure how to impliment 
} 

dbus_bool_t register_item(DBusConnection *connection, DBusMessage *message, void *_data) { 
    DBusError error; 
    char *name; 

    if (!dbus_message_get_args(message, &error, 
       DBUS_TYPE_STRING, &name, 
       DBUS_TYPE_INVALID)) { 
     fprintf(stderr, "Error parsing method args: %s\n", error.message); 
     return FALSE; 
    } 

    watch_name(name, item_unregistered_signal); 
    return TRUE; 
} 

static void check_and_abort(DBusError *error) { 
    if (dbus_error_is_set(error)) { 
     fprintf(stderr, "dbus_err: %s\n", error->message); 
     exit(EXIT_FAILURE); 
    } 
} 

int main() { 
    DBusError error; 
    dbus_error_init(&error); 
    conn = dbus_bus_get(DBUS_BUS_SESSION, &error); 
    check_and_abort(&error); 

    dbus_bus_request_name(conn, "org.freedesktop.StatusNotifierWatcher", 
      DBUS_NAME_FLAG_REPLACE_EXISTING, 
      &error); 
    check_and_abort(&error); 

    dbus_connection_add_filter(conn, register_item, NULL, free); 

    while(1) { 
     dbus_connection_read_write_dispatch(conn, 1000); 
    } 
} 

如果我有衆所周知的名字命名的服務的DBus,我怎麼知道什麼時候該名稱從總線消失?

回答

1

好吧,我想通了這一點,我會張貼誰需要libdbus工作的任何未來可憐的靈魂的答案。

org.freedesktop.DBus發送NameOwnerChanged信號每當任何的DBus名稱變化。可以使用這個信號來跟蹤一個項目是否已經消失,因爲NewOwner參數是一個空字符串。 這個功能可以做到這一點:

static DBusHandlerResult signal_handler(DBusConnection *connection, 
     DBusMessage *message, void *_usr_data) { 

    if (dbus_message_is_signal(message, "org.freedesktop.DBus", 
      "NameOwnerChanged")) { 
     const char *name; 
     const char *old_owner; 
     const char *new_owner; 

     if (!dbus_message_get_args(message, NULL, 
       DBUS_TYPE_STRING, &name, 
       DBUS_TYPE_STRING, &old_owner, 
       DBUS_TYPE_STRING, &new_owner, 
       DBUS_TYPE_INVALID)) { 
      fprintf(stderr, "Error getting OwnerChanged args"); 
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
     } 
     if (strcmp(name, "") != 0) { 
      // Name not lost, just swapped owners 
      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
     } 
     name_lost(name); 
     return DBUS_HANDLER_RESULT_HANDLED; 
    } 
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 
} 

人們還需要增加一個匹配,使你的程序將與這個信號被調用。添加此在main()

dbus_bus_add_match(conn, 
     "type='signal',\ 
     sender='org.freedesktop.DBus',\ 
     interface='org.freedesktop.DBus',\ 
     member='NameOwnerChanged'", 
     &error); 
check_and_abort(&error); 

dbus_connection_add_filter(conn, signal_handler, NULL, free); 
0

對於使用GDBus那些(推薦)代替libdbus(泄氣),等效是g_bus_watch_name()

+0

libdbus不貶值,這是不建議在大多數情況下。實際上,它可能與任何其他庫相比都符合dbus規範。不過謝謝你們的補充,很高興澄清高級圖書館對這些圖書館具有便利功能。 – 4e554c4c

+0

對不起,你是對的;它是dbus-glib,這是非常不贊成的。 libdbus不被棄用,但不鼓勵使用它。 sd-bus通常被認爲是低級別D-Bus使用的更好選擇。我會編輯我的答案。 –

+0

通常由誰來接受?我一直在使用libdbus-1 2周,並且發現它是最輕的DBus實現。另外,libdbus-1是最容易理解的。 sd-dbus有更多的依賴關係,有些系統甚至沒有systemd。 –