gdbus demo程式簡介

來源:互聯網
上載者:User

近期想要寫一個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  * * ===================================================================================== */#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 * * ===================================================================================== */#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 * ===================================================================================== */#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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.