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, NULL,/* user_data */
NULL,/* user_data_free_func */
NULL);/* GError** */
g_assert (registration_id > 0);
}
static void on_name_acquired (GDBusConnection * connection, const gchar * name, gpointer user_data)
{
}
static void on_name_lost (GDBusConnection * connection, const gchar * name, 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, 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, NULL);
bproxy = g_dbus_proxy_new_sync (bcon, G_DBUS_PROXY_FLAGS_NONE, NULL, "org.myapp.JelariServer", "/org/myapp/JelariObject", "org.myapp.JelariInterface", NULL, NULL);
g_dbus_proxy_call (bproxy, "HelloWorld", g_variant_new ("(s)", "Wow"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, (GAsyncReadyCallback) mycallback, NULL);
g_main_loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(g_main_loop);
return 0;
}
运行结果:
$ ./gdbus-xml-client还可以用 gdbus工具查看:
Inside Handle Method Call
Inside mycallback
String from Server is: You typed 'Wow', !!!
$ 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 s property_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,
in u arg_1,
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', !!! "