D-BUS binding tool usage

转发:http://www.emilmont.net/doku.php?id=c:d-bus 

D-BUS

D-Bus is a message bus system, a simple way for applications to talk to one another. In addition to interprocess communication, D-Bus helps coordinate process lifecycle; it makes it simple and reliable to code a “single instance” application or daemon, and to launch applications and daemons on demand when their services are needed.

D-Bus supplies both a system daemon (for events such as “new hardware device added” or “printer queue changed”) and a per-user-login-session daemon (for general IPC needs among user applications).

On the D-Bus are defined only four message types:

  • Method call messages
  • Method return messages
  • Error messages (exception caused by invoking a method)
  • Signal messages

Each D-Bus message contains a signature of the contained data.

D-Bus Object

Every group of calls/signals published on the D-Bus are associated to an object abstraction.

Every object on the D-Bus has a path and an interface defined in an XML file:

service.xml

<?xml version="1.0" encoding="UTF-8" ?>
<node name="/">
    <interface name="org.example.TestService">
        <method name="Method_1">
            <arg name="data_a" type="s" direction = "in"/>
            <arg name="data_b" type="as" direction="out"/>
        </method>
        <signal name="Signal_1"/>
    </interface>
</node>

The type of the arguments can be used by the D-Bus bindings to marshal and un-marshal the data.

The GLib bindings can generate, with the dbus-binding-tool, a “glue” header to be used with a GObject:

dbus-binding-tool --prefix=test_object --mode=glib-server service.xml > service-glue.h 
  • –prefix is the name of the GObject that will implements the service method

The header and the object implementation follow always the same pattern:

test-object.h

#ifndef TEST_OBJECT_H_
    #define TEST_OBJECT_H_
 
    typedef struct TestObject_s {
        GObject parent;
    } TestObject;
	
    typedef struct TestObjectClass_s {
        GObjectClass parent;
    } TestObjectClass;
		
    #define TEST_TYPE_OBJECT            (test_object_get_type())
    #define TEST_OBJECT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), TEST_TYPE_OBJECT, TestObject))
    #define TEST_OBJECT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass))
    #define TEST_IS_OBJECT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), TEST_TYPE_OBJECT))
    #define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT))
    #define TEST_OBJECT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass))
 
    extern GType test_object_get_type(void);
    gboolean method_1_implementation(...) ;
	
#endif /*TEST_OBJECT_H_*/

test-object.c

#include <dbus/dbus-glib.h>
#include <glib-object.h>
#include "test-object.h"
 
G_DEFINE_TYPE(TestObject, test_object, G_TYPE_OBJECT)
 
static void test_object_init(TestObject *obj) {
}
 
/* Signals initialization */
static guint signal = 0;
static void test_object_class_init(TestObjectClass *klass) {
    signal = g_signal_new ("Signal_1", 
        G_OBJECT_CLASS_TYPE (klass), 
    	(G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED),
        0,
        NULL, NULL,
        g_cclosure_marshal_VOID__STRING,
        G_TYPE_NONE, 1, G_TYPE_STRING);
}
 
/* Method implementation */
gboolean method_1(...) {
 
    return TRUE;
}

At initialization, the GObject has to be registered on the D-Bus:

Server

/* Object Initialization */
g_type_init();
dbus_g_object_type_install_info(SOME_TYPE_OBJECT, &dbus_glib_some_object_object_info);
 
/* Main Loop initialization */    
mainloop = g_main_loop_new(NULL, FALSE);
 
/* D-Bus Connection */
bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (!bus) g_error("Couldn't connect to session bus %s", error->message);
bus_proxy = dbus_g_proxy_new_for_name (bus, "org.freedesktop.DBus",  "/org/freedesktop/DBus",  "org.freedesktop.DBus");
 
/* Service registration to the D-Bus */
if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, 
    G_TYPE_STRING, "org.example.TestService", G_TYPE_UINT, 0, G_TYPE_INVALID,
    G_TYPE_UINT, &request_name_result, G_TYPE_INVALID))
        g_error("Failed to acquire org.example.TestService: %s", error->message);
 
/* Bounding of an instance of the object that implements the service on D-Bus */
obj = g_object_new(TEST_TYPE_OBJECT, NULL);
dbus_g_connection_register_g_object(bus, "/TestObject", G_OBJECT (obj));
 
/* Main Loop */
g_main_loop_run(mainloop);

Client

/* GLib initing */
g_type_init();
mainloop = g_main_loop_new(NULL, FALSE);
 
/* D-Bus Connection*/
bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error);
if (!bus) fatal_gerror("Couldn't connect to session bus", error);
  
/* Construction of a new proxy for the remote object */
remote_object = dbus_g_proxy_new_for_name(bus, "org.example.TestService", "/org/example/TestService/object",  "org.designfu.TestService");
if (!remote_object) g_error("Failed to get name owner: %s", error->message);
 
/* Remote object method call */
if (!dbus_g_proxy_call (remote_object, "HelloWorld", &error,
    G_TYPE_STRING, "Hello from example-client.c!", G_TYPE_INVALID,
    G_TYPE_STRV, &reply_list, G_TYPE_INVALID))
        g_error("Failed to complete HelloWorld: %s", error->message);
 
/* Connection to a remote object signal */
dbus_g_proxy_add_signal (remote_object, "HelloSignal", G_TYPE_STRING, G_TYPE_INVALID);
dbus_g_proxy_connect_signal(remote_object, "HelloSignal", G_CALLBACK (hello_signal_handler), NULL, NULL);
 
/* Main Loop */
g_main_loop_run(mainloop);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值