使用 DBUS (2): 嵌入式XML描述接口

server:

#include <gio/gio.h>
#include <stdlib.h>

#ifdef G_OS_UNIX
//#include <gio/gunixfdlist.h>
/* For STDOUT_FILENO */
#include <unistd.h>
#endif

static GDBusNodeInfo *introspection_data = NULL;

/* Introspection data for the service we are exporting */
static const gchar introspection_xml[] =
	"<node>"
	"<interface name='org.myapp.JelariInterface'>"
	"<method name='HelloWorld'>"
	"<arg type='s' name='greeting' direction='in'/>" 
        "<arg type='s' name='response' direction='out'/>"
        "</method>"
        "</interface>" 
         "</node>";

static void
handle_method_call (GDBusConnection * connection,const gchar * sender,const gchar * object_path,const gchar * interface_name,const gchar * method_name,GVariant * parameters,GDBusMethodInvocation * invocation,gpointer user_data)
{
	g_printf ("Inside Handle Method Call \n");

	if (g_strcmp0 (method_name,"HelloWorld") == 0)
	{
		const gchar *greeting;

		gchar *response;
		g_variant_get (parameters,"(&s)",&greeting);
		response = g_strdup_printf ("You typed '%s',!!! ",greeting);

		g_dbus_method_invocation_return_value (invocation,g_variant_new ("(s)",response));
//g_print ("Sending %s  -> to the client ",response);

	}
}

static const GDBusInterfaceVTable interface_vtable = {
	handle_method_call,NULL,NULL
};

static void on_bus_acquired (GDBusConnection * connection,const gchar * name,gpointer user_data)
{
	g_print ("\n Inside on_bus_acquired \n");

	guint registration_id;

	registration_id = g_dbus_connection_register_object (connection,"/org/myapp/JelariObject",introspection_data->interfaces[0],&interface_vtable,/* user_data */
		NULL,/* user_data_free_func */
		NULL);					/* GError** */
	g_assert (registration_id > 0);

}

static void on_name_acquired (GDBusConnection * connection,gpointer user_data)
{
}

static void on_name_lost (GDBusConnection * connection,gpointer user_data)
{
	exit (1);
}

int main (int argc,char **argv)
{
	guint owner_id;
	GMainLoop *loop;
	g_type_init ();
	introspection_data = g_dbus_node_info_new_for_xml (introspection_xml,NULL);
	g_assert (introspection_data != NULL);

	owner_id = g_bus_own_name (G_BUS_TYPE_SESSION,"org.myapp.JelariServer",G_BUS_NAME_OWNER_FLAGS_NONE,on_bus_acquired,on_name_acquired,on_name_lost,NULL);

	g_print ("\n Owner id is %d ",owner_id);
	loop = g_main_loop_new (NULL,FALSE);
	g_main_loop_run (loop);

	g_bus_unown_name (owner_id);

	g_dbus_node_info_unref (introspection_data);

}

client:
#include <gio/gio.h>
#include <stdlib.h>

#ifdef G_OS_UNIX
//#include <gio/gunixfdlist.h>
/* For STDOUT_FILENO */
#include <unistd.h>
#endif

GDBusProxy *bproxy;
GMainLoop * g_main_loop;

void mycallback (GObject * gobj,GAsyncResult * res,gpointer user_data)
{
	g_printf ("\n Inside mycallback\n ");

	GError *error;
	GVariant *result;
	gchar *str;

	error = NULL;
	result = g_dbus_proxy_call_finish (bproxy,res,&error);
	g_variant_get (result,"(s)",&str);
	g_print ("String from Server is: %s \n",str);
	g_main_loop_quit(g_main_loop);
	exit(0);
}

int main (int argc,char **argv)
{
	GDBusConnection *bcon;
	GMainLoop *loop;

	g_type_init ();
	bcon = g_bus_get_sync (G_BUS_TYPE_SESSION,NULL);
	bproxy = g_dbus_proxy_new_sync (bcon,G_DBUS_PROXY_FLAGS_NONE,"org.myapp.JelariInterface",NULL);
	g_dbus_proxy_call (bproxy,"HelloWorld","Wow"),G_DBUS_CALL_FLAGS_NONE,-1,(GAsyncReadyCallback) mycallback,NULL);

	g_main_loop = g_main_loop_new(NULL,FALSE);
	g_main_loop_run(g_main_loop);
	return 0;
}

运行结果:
$ ./gdbus-xml-client 
Inside Handle Method Call 

 Inside mycallback
 String from Server is: You typed 'Wow',!!!
还可以用 gdbus工具查看:
$ gdbus introspect --session --dest org.myapp.JelariServer --object-path /org/myapp/JelariObject  

node /org/myapp/JelariObject {
  interface org.freedesktop.DBus.Properties {
    methods:
      Get(in  s interface_name,in  s property_name,out v value);
      GetAll(in  s interface_name,out a{sv} properties);
      Set(in  s interface_name,in  v value);
    signals:
      PropertiesChanged(s interface_name,a{sv} changed_properties,as invalidated_properties);
    properties:
  };
  interface org.freedesktop.DBus.Introspectable {
    methods:
      Introspect(out s xml_data);
    signals:
    properties:
  };
  interface org.freedesktop.DBus.Peer {
    methods:
      Ping();
      GetMachineId(out s machine_uuid);
    signals:
    properties:
  };
  interface org.myapp.JelariInterface {
    methods:
      HelloWorld(in  s greeting,out s response);
    signals:
    properties:
  };
};

对照标准的 DBUS的接口:
$  gdbus introspect --system --dest org.freedesktop.DBus --object-path /org/freedesktop/DBus
node /org/freedesktop/DBus {
  interface org.freedesktop.DBus {
    methods:
      Hello(out s arg_0);
      RequestName(in  s arg_0,in  u arg_1,out u arg_2);
      ReleaseName(in  s arg_0,out u arg_1);
      StartServiceByName(in  s arg_0,out u arg_2);
      UpdateActivationEnvironment(in  a{ss} arg_0);
      NameHasOwner(in  s arg_0,out b arg_1);
      ListNames(out as arg_0);
      ListActivatableNames(out as arg_0);
      AddMatch(in  s arg_0);
      RemoveMatch(in  s arg_0);
      GetNameOwner(in  s arg_0,out s arg_1);
      ListQueuedOwners(in  s arg_0,out as arg_1);
      GetConnectionUnixUser(in  s arg_0,out u arg_1);
      GetConnectionUnixProcessID(in  s arg_0,out u arg_1);
      GetAdtAuditSessionData(in  s arg_0,out ay arg_1);
      GetConnectionSELinuxSecurityContext(in  s arg_0,out ay arg_1);
      GetConnectionAppArmorSecurityContext(in  s arg_0,out s arg_1);
      ReloadConfig();
      GetId(out s arg_0);
    signals:
      NameOwnerChanged(s arg_0,s arg_1,s arg_2);
      NameLost(s arg_0);
      NameAcquired(s arg_0);
    properties:
  };
  interface org.freedesktop.DBus.Introspectable {
    methods:
      Introspect(out s arg_0);
    signals:
    properties:
  };
};

也可以使用 dbus-send 直接调用server的函数:

$ dbus-send --print-reply --dest=org.myapp.JelariServer /org/myapp/JelariObject  org.myapp.JelariInterface.HelloWorld string:hi
Inside Handle Method Call 
method return sender=:1.296 -> dest=:1.316 reply_serial=2
   string "You typed 'hi',!!! "

相关文章

php输出xml格式字符串
J2ME Mobile 3D入门教程系列文章之一
XML轻松学习手册
XML入门的常见问题(一)
XML入门的常见问题(三)
XML轻松学习手册(2)XML概念