Recently want to write a Gdbus demo program, look up the information, found seemingly gdbus between the IPC communication is divided into two, one is based on the system bus, one is based on the session, I through the session of the way of communication simple write a peer to the demo program.
The. h and. c files are generated first through Gdbus-codegen, and then through the interface of the glib Gio, a client and a server are written separately, the client communicates synchronously with the server by means of method, and the server sends a signal notification to the client by signal.
The service-side flowchart is as follows
The client flowchart is as follows
The program is built using Automake, with the following structure
├──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
The contents of each file are posted below
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 represents a string, I represents a number, where direction in represents the incoming parameter, that is, the value sent, out represents the argument, that is, the obtained value
The signal represents the signal sent by the service side, where a number is sent
makefile.am
Am_cflags = $ (glib_cflags) $ (gio_cflags)-g
am_cppflags =-i$ (top_srcdir)/private-include built_sources
= Building.c Building.h
dist_noinst_data = building.xml
bin_programs = gdbus_server gdbus_client
gdbus_ server_sources = gdbus_server.c \
building.c Building.h
gdbus_server_ldadd = $ (glib_libs) $ (gio_libs)
gdbus_client_sources = gdbus_client.c \
buildingclient.c BuildingClient.h
gdbus_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)
The building.xml is processed using Gdbus-codegen in makefile.am, generating Building.h building.c,
–interface-prefix represents omitting the prefix name com.qiaotsh.Building, so that in the makefile will start with test as the function, otherwise the string looks more redundant, is the beginning of comqiaobuildingtest, the purpose is to enhance readability, –generate-c-code representative generates C code
Gdbus_client.c
/* * ===================================================================================== * * Filename:gdbus_c LIENT.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, "Co
M.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;
}
It is noteworthy that the parameters of Test_status_handler are not arbitrarily defined, and the specific form is described in detail in building.c
Gdbus_server.c
/* * ===================================================================================== * * Filename:gdbus_c LIENT.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 CA
LL:%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 obj Ect. Reason:%s.\n ", ErroR->message);
G_error_free (Error); }} void Gbusnameacquired_callback (Gdbuscon Nection *connection, const Gchar *name, Gpointer user_data) {printf ("Gbusnameacquired_callback has been
En invoked\n "); } void Gbusnamelost_callback (Gdbusconnection *connection, const Gchar *name, Gpointer user_data) {p
rintf ("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 (n, (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;
}
Similarly, On_handle_set_version's parameters are defined in BUILDING.C, not arbitrarily defined
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); c40/> #endif
Gdbus_client.h is empty, because I'm lazy.
Common.h is empty, maybe he'll use it later.
autogen.sh
#!/bin/sh
autoreconf--verbose--force--install--make | | {
echo ' autogen.sh failed ';
Exit 1;
}
echo
echo "Now can ' configure ' and ' 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_ar
lt_init
ac_prog_cc
ac_ 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
The Compile method is as follows
./autogen.sh
./configure $CONFIGURE _flags–prefix=/usr
Make
Make install
Generate Gdbus_server and Gdbus_client
The execution effect is as follows
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
SIG NAL received 5
Signal received 5
Signal received 5
Signal received 5
Signal received 5
Signal Rec Eived 5
Signal received 5
Signal received 5
Signal received 5
Signal received 5
Signal received 5