本文介绍如何在linux系统使用gdbus进行进程,分为服务端和客户端。总体上是比较简单的,奈何gdbus的帮助文档实在太简单,网络上的资料也比较少。希望本文对需要使用gdbus的开发人员有帮助。
第一步,是编写interface和相应函数的xml文件(D-Bus introspection XML file),供之后借助gdbus-codegen来创建服务端和客户端相应的代码。比如:
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/com/alibaba/Building">
<interface name="com.alibaba.Building.Test">
<method name="SetVersion">
<arg name="version" type="s" direction="in" />
</method>
<signal name="TestStatus">
<arg name="status" type="i" />
</signal>
</interface>
</node>
一,服务端。
有了xml文件,就可以创建服务端需要的代码文件,使用如下命令:
./gdbus-codegen --generate-c-code=Building Building.xml
在当前目录会出现两个文件Building.[hc],这里也贴出它们的代码。
Building.h
/*
* Generated by gdbus-codegen 2.30.3. DO NOT EDIT.
*
* The license of this code is the same as for the source it was derived from.
*/
#ifndef __BUILDING_H__
#define __BUILDING_H__
#include <gio/gio.h>
G_BEGIN_DECLS
/* ------------------------------------------------------------------------ */
/* Declarations for com.alibaba.Building.Test */
#define TYPE_COM_ALIBABA_BUILDING_TEST (com_alibaba_building_test_get_type ())
#define COM_ALIBABA_BUILDING_TEST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_COM_ALIBABA_BUILDING_TEST, ComAlibabaBuildingTest))
#define IS_COM_ALIBABA_BUILDING_TEST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_COM_ALIBABA_BUILDING_TEST))
#define COM_ALIBABA_BUILDING_TEST_GET_IFACE(o) (G_TYPE_INSTANCE_GET_INTERFACE ((o), TYPE_COM_ALIBABA_BUILDING_TEST, ComAlibabaBuildingTestIface))
struct _ComAlibabaBuildingTest;
typedef struct _ComAlibabaBuildingTest ComAlibabaBuildingTest;
typedef struct _ComAlibabaBuildingTestIface ComAlibabaBuildingTestIface;
struct _ComAlibabaBuildingTestIface
{
GTypeInterface parent_iface;
gboolean (*handle_set_version) (
ComAlibabaBuildingTest *object,
GDBusMethodInvocation *invocation,
const gchar *arg_version);
void (*test_status) (
ComAlibabaBuildingTest *object,
gint arg_status);
};
GType com_alibaba_building_test_get_type (void) G_GNUC_CONST;
GDBusInterfaceInfo *com_alibaba_building_test_interface_info (void);
guint com_alibaba_building_test_override_properties (GObjectClass *klass, guint property_id_begin);
/* D-Bus method call completion functions: */
void com_alibaba_building_test_complete_set_version (
ComAlibabaBuildingTest *object,
GDBusMethodInvocation *invocation);
/* D-Bus signal emissions functions: */
void com_alibaba_building_test_emit_test_status (
ComAlibabaBuildingTest *object,
gint arg_status);
/* D-Bus method calls: */
void com_alibaba_building_test_call_set_version (
ComAlibabaBuildingTest *proxy,
const gchar *arg_version,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean com_alibaba_building_test_call_set_version_finish (
ComAlibabaBuildingTest *proxy,
GAsyncResult *res,
GError **error);
gboolean com_alibaba_building_test_call_set_version_sync (
ComAlibabaBuildingTest *proxy,
const gchar *arg_version,
GCancellable *cancellable,
GError **error);
/* ---- */
#define TYPE_COM_ALIBABA_BUILDING_TEST_PROXY (com_alibaba_building_test_proxy_get_type ())
#define COM_ALIBABA_BUILDING_TEST_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_COM_ALIBABA_BUILDING_TEST_PROXY, ComAlibabaBuildingTestProxy))
#define COM_ALIBABA_BUILDING_TEST_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TYPE_COM_ALIBABA_BUILDING_TEST_PROXY, ComAlibabaBuildingTestProxyClass))
#define COM_ALIBABA_BUILDING_TEST_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_COM_ALIBABA_BUILDING_TEST_PROXY, ComAlibabaBuildingTestProxyClass))
#define IS_COM_ALIBABA_BUILDING_TEST_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_COM_ALIBABA_BUILDING_TEST_PROXY))
#define IS_COM_ALIBABA_BUILDING_TEST_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_COM_ALIBABA_BUILDING_TEST_PROXY))
typedef struct _ComAlibabaBuildingTestProxy ComAlibabaBuildingTestProxy;
typedef struct _ComAlibabaBuildingTestProxyClass ComAlibabaBuildingTestProxyClass;
typedef struct _ComAlibabaBuildingTestProxyPrivate ComAlibabaBuildingTestProxyPrivate;
struct _ComAlibabaBuildingTestProxy
{
/*< private >*/
GDBusProxy parent_instance;
ComAlibabaBuildingTestProxyPrivate *priv;
};
struct _ComAlibabaBuildingTestProxyClass
{
GDBusProxyClass parent_class;
};
GType com_alibaba_building_test_proxy_get_type (void) G_GNUC_CONST;
void com_alibaba_building_test_proxy_new (
GDBusConnection *connection,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
ComAlibabaBuildingTest *com_alibaba_building_test_proxy_new_finish (
GAsyncResult *res,
GError **error);
ComAlibabaBuildingTest *com_alibaba_building_test_proxy_new_sync (
GDBusConnection *connection,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GError **error);
void com_alibaba_building_test_proxy_new_for_bus (
GBusType bus_type,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
ComAlibabaBuildingTest *com_alibaba_building_test_proxy_new_for_bus_finish (
GAsyncResult *res,
GError **error);
ComAlibabaBuildingTest *com_alibaba_building_test_proxy_new_for_bus_sync (
GBusType bus_type,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GError **error);
/* ---- */
#define TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON (com_alibaba_building_test_skeleton_get_type ())
#define COM_ALIBABA_BUILDING_TEST_SKELETON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON, ComAlibabaBuildingTestSkeleton))
#define COM_ALIBABA_BUILDING_TEST_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON, ComAlibabaBuildingTestSkeletonClass))
#define COM_ALIBABA_BUILDING_TEST_SKELETON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON, ComAlibabaBuildingTestSkeletonClass))
#define IS_COM_ALIBABA_BUILDING_TEST_SKELETON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON))
#define IS_COM_ALIBABA_BUILDING_TEST_SKELETON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), TYPE_COM_ALIBABA_BUILDING_TEST_SKELETON))
typedef struct _ComAlibabaBuildingTestSkeleton ComAlibabaBuildingTestSkeleton;
typedef struct _ComAlibabaBuildingTestSkeletonClass ComAlibabaBuildingTestSkeletonClass;
typedef struct _ComAlibabaBuildingTestSkeletonPrivate ComAlibabaBuildingTestSkeletonPrivate;
struct _ComAlibabaBuildingTestSkeleton
{
/*< private >*/
GDBusInterfaceSkeleton parent_instance;
ComAlibabaBuildingTestSkeletonPrivate *priv;
};
struct _ComAlibabaBuildingTestSkeletonClass
{
GDBusInterfaceSkeletonClass parent_class;
};
GType com_alibaba_building_test_skeleton_get_type (void) G_GNUC_CONST;
ComAlibabaBuildingTest *com_alibaba_building_test_skeleton_new (void);
G_END_DECLS
#endif /* __BUILDING_H__ */
Building.c
/*
* Generated by gdbus-codegen 2.30.3. DO NOT EDIT.
*
* The license of this code is the same as for the source it was derived from.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Building.h"
#ifdef G_OS_UNIX
# include <gio/gunixfdlist.h>
#endif
typedef struct
{
GDBusArgInfo parent_struct;
gboolean use_gvariant;
} _ExtendedGDBusArgInfo;
typedef struct
{
GDBusMethodInfo parent_struct;
const gchar *signal_name;
gboolean pass_fdlist;
} _ExtendedGDBusMethodInfo;
typedef struct
{
GDBusSignalInfo parent_struct;
const gchar *signal_name;
} _ExtendedGDBusSignalInfo;
typedef struct
{
GDBusPropertyInfo parent_struct;
const gchar *hyphen_name;
gboolean use_gvariant;
} _ExtendedGDBusPropertyInfo;
typedef struct
{
GDBusInterfaceInfo parent_struct;
const gchar *hyphen_name;
} _ExtendedGDBusInterfaceInfo;
typedef struct
{
const _ExtendedGDBusPropertyInfo *info;
guint prop_id;
GValue orig_value; /* the value before the change */
} ChangedProperty;
static void
_changed_property_free (ChangedProperty *data)
{
g_value_unset (&data->orig_value);
g_free (data);
}
static gboolean
_g_strv_equal0 (gchar **a, gchar **b)
{
gboolean ret = FALSE;
guint n;
if (a == NULL && b == NULL)
{
ret = TRUE;
goto out;
}
if (a == NULL || b == NULL)
goto out;
if (g_strv_length (a) != g_strv_length (b))
goto out;
for (n = 0; a[n] != NULL; n++)
if (g_strcmp0 (a[n], b[n]) != 0)
goto out;
ret = TRUE;
out:
return ret;
}
static gboolean
_g_variant_equal0 (GVariant *a, GVariant *b)
{
gboolean ret = FALSE;
if (a == NULL && b == NULL)
{
ret = TRUE;
goto out;
}
if (a == NULL