gdbus demo程序简介
来源:互联网 发布:2015java面试宝典下载 编辑:程序博客网 时间:2024/06/05 04:25
近期想要写一个gdbus的demo程序,查阅了一下资料,发现貌似gdbus之间的IPC通信分为两种,一种是基于system总线,一种是基于session,我通过session通信的方式简单写了一个p2p的demo程序。
首先通过gdbus-codegen 生成.h 和.c 文件,然后通过glib gio的接口分别写了一个客户端和服务端,客户端通过method与服务端进行同步通信,服务端通过signal 主动向客户端发送信号通知。
服务端流程图如下
客户端流程图如下
程序使用automake进行构建,结构如下
├── autogen.sh
├── configure.ac
├── LICENSE
├── Makefile.am
├── private-include
│ ├── common.h
│ ├── gdbus_client.h
│ └── gdbus_server.h
├── README.md
└── src
├── Building.xml
├── gdbus_client.c
├── gdbus_server.c
└── Makefile.am
下面把各文件的内容贴上
Building.xml
<?xml version="1.0" encoding="UTF-8"?><node> <interface name="com.qiaotsh.Building.Test"> <method name="SetVersion"> <arg name="version" type="s" direction="in"/> <arg name="reply" type="s" direction="out"/> </method> <signal name="TestStatus"> <arg name="status" type="i"/> </signal> </interface></node>
method中s代表字符串,i代表数字,其中direction中in代表入参,即发送的值,out代表出参,即获取的值
signal代表服务端发送的信号,此处表示发送一个数字
Makefile.am
AM_CFLAGS = $(GLIB_CFLAGS) $(GIO_CFLAGS) -gAM_CPPFLAGS = -I$(top_srcdir)/private-includeBUILT_SOURCES = Building.c Building.hdist_noinst_DATA = Building.xmlbin_PROGRAMS = gdbus_server gdbus_clientgdbus_server_SOURCES = gdbus_server.c \ Building.c Building.hgdbus_server_LDADD = $(GLIB_LIBS) $(GIO_LIBS)gdbus_client_SOURCES = gdbus_client.c \ BuildingClient.c BuildingClient.hgdbus_client_LDADD = $(GLIB_LIBS) $(GIO_LIBS)Building.c Building.h : Building.xml gdbus-codegen --interface-prefix=com.qiaotsh.Building --generate-c-code=Building $<MOSTLYCLEANFILES = $(BUILT_SOURCES)
Makefile.am中使用gdbus-codegen对Building.xml进行处理,生成Building.h Building.c,
–interface-prefix代表省略前缀名com.qiaotsh.Building,这样在生成文件中将以Test为函数开头,否则字符串看起来比较冗余,是comqiaoBuildingtest开头,目的是增强可读性,–generate-c-code代表生成C语言代码
gdbus_client.c
/* * ===================================================================================== * * Filename: gdbus_client.c * * Description: * * Version: 1.0 * Created: 02/17/2017 08:28:34 AM * Revision: none * Compiler: gcc * * Author: qiaotsh (), qiaotsh@neusoft.com * Organization: www.neusoft.com * * ===================================================================================== */#include <glib.h>#include <gio/gio.h>#include <unistd.h>#include "Building.h"#include "gdbus_client.h"static gboolean test_status_handler(Test* object,gint status,gpointer user_data){ g_print("signal received %d\n",status); return TRUE;}static void cb_OwnerNameChangedNotify(GObject *object, GParamSpec *pspec, gpointer userdata){ gchar *pname_owner = NULL; pname_owner = g_dbus_proxy_get_name_owner((GDBusProxy*)object); if (NULL != pname_owner){ g_print("DBus service is ready!\n"); g_free(pname_owner); } else{ g_print("DBus service is NOT ready!\n"); g_free(pname_owner); }}int main(int argc, char *argv[]){ Test *proxy=NULL; GError *error = NULL; GMainLoop* loop = NULL; proxy = test_proxy_new_for_bus_sync ( G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "com.qiaotsh.Building.Test", "/com/qiaotsh/Building/Test", NULL, &error); if(0 == proxy) { g_print("InitDBusCommunication: Failed to create proxy. Reason: %s.\n", error->message); } g_signal_connect(proxy,"test-status",G_CALLBACK(test_status_handler),NULL); char *reply = NULL; test_call_set_version_sync (proxy, "hello world", &reply,NULL, &error); g_print("sync reply = %s\n",reply); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); g_object_unref(proxy); return 0;}
值得注意的是test_status_handler的参数不是随便定义的,具体形式在Building.c中有详细描述
gdbus_server.c
/* * ===================================================================================== * * Filename: gdbus_client.c * * Description: * * Version: 1.0 * Created: 02/17/2017 08:28:34 AM * Revision: none * Compiler: gcc * * Author: qiaotsh (), qiaotsh@neusoft.com * Organization: www.neusoft.com * * ===================================================================================== */#include<stdio.h>#include<gio/gio.h>#include<glib.h>#include<assert.h>#include"Building.h"#include"gdbus_server.h"static Test* skeleton=NULL;static gboolean Emit_Test_Status(gconstpointer p) { g_print("Emit_Test_Status() is called.\n"); gint status = 5; test_emit_test_status (skeleton,status); return TRUE; } static gboolean on_handle_set_version(Test* skeleton, GDBusMethodInvocation *invocation, const gchar *greeting, gpointer user_data){ g_print("Method call: %s\n", greeting); char* reply = "getSuccess"; test_complete_set_version (skeleton,invocation,reply); return TRUE;}void GBusAcquired_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data){ GError *error = NULL; printf("GBusAcquired_Callback has been invoked\n"); printf("GBusAcquired_Callback the name = %s\n",name); printf("GBusAcquired_Callback the user_data = %s\n",(char*)user_data); skeleton = test_skeleton_new (); g_signal_connect(skeleton,"handle-set-version",G_CALLBACK(on_handle_set_version),NULL); g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skeleton), connection, "/com/qiaotsh/Building/Test", &error); if(error != NULL){ g_print("Error: Failed to export object. Reason: %s.\n", error->message); g_error_free(error); } }void GBusNameAcquired_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data){ printf("GBusNameAcquired_Callback has been invoked\n");}void GBusNameLost_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data){ printf("GBusNameLost_Callback has been invoked\n");}int main(int argc,char* argv[]){ char* s = "qiaotsh"; GMainLoop* loop = NULL; guint own_id = g_bus_own_name (G_BUS_TYPE_SESSION, "com.qiaotsh.Building.Test", G_BUS_NAME_OWNER_FLAGS_NONE, GBusAcquired_Callback, GBusNameAcquired_Callback, GBusNameLost_Callback, (gpointer)s, NULL); /* * emit my signal1 every 1 second to trigger example communication */ g_timeout_add(1000, (GSourceFunc)Emit_Test_Status, NULL); loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(loop); g_bus_unown_name(own_id); return 0;}
同理,on_handle_set_version的参数在Building.c中有定义,不可随便定义
gdbus_server.h
/* * ===================================================================================== * * Filename: gdbus_server.h * * Description: * * Version: 1.0 * Created: 10/31/2017 10:11:19 AM * Revision: none * Compiler: gcc * * Author: qiaotsh (), qiaotsh@neusoft.com * Organization: www.neusoft.com * * ===================================================================================== */#ifndef __GDBUS_SERVER_H_#define __GDBUS_SERVER_H_#define GDBUS_API __attribute__((visibility("hidden")))GDBUS_API void GBusAcquired_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data);GDBUS_API void GBusNameAcquired_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data);GDBUS_API void GBusNameLost_Callback (GDBusConnection *connection, const gchar *name, gpointer user_data);#endif
gdbus_client.h是空的,因为我懒
common.h是空的,没准以后会用上呢
autogen.sh
#!/bin/shautoreconf --verbose --force --install --make || { echo 'autogen.sh failed'; exit 1;}echoecho "Now you can 'configure' then 'make'"echo
configure.ac
AC_INIT([gdbus-example], [0.1], [onurmark1@gmail.com])AC_CONFIG_AUX_DIR([build-aux])AC_CONFIG_MACRO_DIR([m4])AM_INIT_AUTOMAKE([foreign -Wall -Werror])AM_PROG_ARLT_INITAC_PROG_CCAC_CONFIG_HEADERS([config.h])AC_CONFIG_FILES([Makefile src/Makefile ])PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.40.2])PKG_CHECK_MODULES([GIO], [gio-unix-2.0 >= 2.40.2])AC_OUTPUT
编译方法如下
./autogen.sh
./configure $CONFIGURE_FLAGS –prefix=/usr
make
make install
生成gdbus_server 和gdbus_client
执行效果如下
gdbus_server
GBusAcquired_Callback has been invoked
GBusAcquired_Callback the name = com.qiaotsh.Building.Test
GBusAcquired_Callback the user_data = qiaotsh
GBusNameAcquired_Callback has been invoked
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Method call: hello world
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
Emit_Test_Status() is called.
gdbus_client
sync reply = getSuccess
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
signal received 5
- gdbus demo程序简介
- Gdbus
- GDBus 通信机制介绍及Demo版本
- Win32 API编程简介Demo程序
- Win32 API编程简介Demo程序
- Win32 API编程简介Demo程序
- gdbus 笔记
- demo简介
- gdbus 中的 method call
- gdbus移植至mips
- netty简介 demo
- Dubbo 简介及demo
- 守护进程 demo程序
- pipe demo小程序
- 网上程序DEMO
- ABAP demo 程序
- Dui程序Demo
- iOS基础程序Demo
- 第十周项目3中序线索化二叉树的算法验证
- zookeeper与dubbo-admin配置説明
- MongoDB中使用MapReduce来进行聚合操作
- 10月2日--11月12日(1小时,剩2887小时)
- [datapump] ORA-39034: Table TABLE_DATA:<table Name> does not exist.
- gdbus demo程序简介
- SDL 实现马赛克
- 有序链表的插入
- python -零基础
- 11.7-
- Communications Among Activities and Fragments
- CodeBlocks使用小技巧
- 第十周项目4哈夫曼编码的算法验证
- 测试“我”对你的心意!