Browse Source

feat: gdbus mix demo

master
dnomd343 3 years ago
parent
commit
ccba977508
  1. 7
      gdbus-mix-demo/CMakeLists.txt
  2. 13
      gdbus-mix-demo/client/CMakeLists.txt
  3. 64
      gdbus-mix-demo/client/client.c
  4. 4
      gdbus-mix-demo/gdbus/CMakeLists.txt
  5. 12
      gdbus-mix-demo/gdbus/interface.xml
  6. 23
      gdbus-mix-demo/includes/client.h
  7. 23
      gdbus-mix-demo/includes/server.h
  8. 13
      gdbus-mix-demo/server/CMakeLists.txt
  9. 63
      gdbus-mix-demo/server/server.c

7
gdbus-mix-demo/CMakeLists.txt

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.16)
set(CMAKE_CXX_STANDARD 14)
project(gdbus_mix_demo)
add_subdirectory(gdbus)
add_subdirectory(client)
add_subdirectory(server)

13
gdbus-mix-demo/client/CMakeLists.txt

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.16)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/includes)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/gdbus)
INCLUDE_DIRECTORIES(/usr/include/glib-2.0)
INCLUDE_DIRECTORIES(/usr/include/gio-unix-2.0)
INCLUDE_DIRECTORIES(/usr/lib/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/i386-linux-gnu/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/x86_64-linux-gnu/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/aarch64-linux-gnu/glib-2.0/include)
add_executable(client client.c ${PROJECT_SOURCE_DIR}/gdbus/gdbus_demo_gen.c)
target_link_libraries(client rt pthread gio-2.0 glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0)

64
gdbus-mix-demo/client/client.c

@ -0,0 +1,64 @@
#include "client.h"
// 进程主循环函数
static void* start_main_loop(void* args) {
g_main_loop_run(main_loop);
}
// 接收完成信号
static gboolean receive_signal(ComGdbusDemo *object, const gchar *payload, gpointer userdata) {
complete = true;
return true;
}
// 发送一段文字并获取返回
static void method_call(const gchar *str_send) {
GError *error = NULL;
gchar *str_return = NULL;
g_print("Send -> %s\n", str_send);
com_gdbus_demo_call_show_data_sync(proxy, str_send, &str_return, NULL, &error); // 发送请求
if (error != NULL) { // 发送请求失败
g_print("Failed to call method: %s.\n", error->message);
g_error_free(error);
}
g_print("Return -> %s\n", str_return);
g_free(str_return);
}
// 初始化DBus连接
bool init_dbus_client() {
GError *proxy_error = NULL;
GError *connect_error = NULL;
connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &connect_error); // 建立连接
if (connect_error != NULL) { // 连接失败
g_print("Failed to connect dbus: %s.\n", connect_error->message);
g_error_free(connect_error);
return false;
}
proxy = com_gdbus_demo_proxy_new_sync(connection, G_DBUS_PROXY_FLAGS_NONE, "com.gdbus.demo",
"/com/gdbus/object", NULL, &proxy_error); // 创建Proxy
if (proxy == 0) { // 创建Proxy失败
g_print("Failed to create proxy: %s.\n", proxy_error->message);
g_error_free(proxy_error);
return false;
}
return true;
}
// client向server发送一段文本,server返回成功并进行处理,处理完成后发送一个信号
int main() {
pthread_t tid;
if (!init_dbus_client()) { // 初始化DBus失败
return -1;
}
g_print("DBus init successfully.\n"); // DBus连接成功
method_call("This is a sentence for test."); // 发送请求
g_print("Wait for signal...");
main_loop= g_main_loop_new(NULL, FALSE); // 创建主循环对象
g_signal_connect(proxy, "complete", G_CALLBACK(receive_signal), NULL); // 监听信号
pthread_create(&tid, NULL, start_main_loop, NULL); // 创建线程 进入主循环
while (!complete); // 循环等待server完成
g_print("OK\n");
return 0;
}

4
gdbus-mix-demo/gdbus/CMakeLists.txt

@ -0,0 +1,4 @@
cmake_minimum_required(VERSION 3.16)
EXECUTE_PROCESS(COMMAND gdbus-codegen --generate-c-code
${PROJECT_SOURCE_DIR}/gdbus/gdbus_demo_gen ${PROJECT_SOURCE_DIR}/gdbus/interface.xml)

12
gdbus-mix-demo/gdbus/interface.xml

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<node>
<interface name="com.gdbus.demo">
<method name="ShowData">
<arg name="content" type="s" direction="in"/>
<arg name="response" type="s" direction="out"/>
</method>
<signal name="Complete">
<arg name="sig" type="s"/>
</signal>
</interface>
</node>

23
gdbus-mix-demo/includes/client.h

@ -0,0 +1,23 @@
#ifndef _CLIENT_H_
#define _CLIENT_H_
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <glib.h>
#include <gio/gio.h>
#include "gdbus_demo_gen.h"
bool complete = false;
static GMainLoop *main_loop = NULL;
static ComGdbusDemo *proxy = NULL;
static GDBusConnection *connection = NULL;
bool init_dbus_client();
static void* start_main_loop(void*);
static void method_call(const gchar*);
static gboolean receive_signal(ComGdbusDemo*, const gchar*, gpointer);
#endif

23
gdbus-mix-demo/includes/server.h

@ -0,0 +1,23 @@
#ifndef _SERVER_H_
#define _SERVER_H_
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
#include <glib.h>
#include <gio/gio.h>
#include "gdbus_demo_gen.h"
static GMainLoop *main_loop = NULL;
static ComGdbusDemo *skeleton = NULL;
static GDBusConnection *connection = NULL;
void init_dbus_server();
static void* start_main_loop(void*);
static void gdbus_acquired_callback(GDBusConnection*, const gchar*, gpointer);
static void gdbus_name_acquired_callback(GDBusConnection*, const gchar*, gpointer);
static void gdbus_name_lost_callback(GDBusConnection*, const gchar*, gpointer);
static gboolean receive_text(ComGdbusDemo*, GDBusMethodInvocation*, const gchar*, gpointer);
#endif

13
gdbus-mix-demo/server/CMakeLists.txt

@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.16)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/includes)
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/gdbus)
INCLUDE_DIRECTORIES(/usr/include/glib-2.0)
INCLUDE_DIRECTORIES(/usr/include/gio-unix-2.0)
INCLUDE_DIRECTORIES(/usr/lib/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/i386-linux-gnu/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/x86_64-linux-gnu/glib-2.0/include)
INCLUDE_DIRECTORIES(/usr/lib/aarch64-linux-gnu/glib-2.0/include)
add_executable(server server.c ${PROJECT_SOURCE_DIR}/gdbus/gdbus_demo_gen.c)
target_link_libraries(server rt pthread gio-2.0 glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0)

63
gdbus-mix-demo/server/server.c

@ -0,0 +1,63 @@
#include "server.h"
// 进程主循环函数
static void* start_main_loop(void* args) {
g_main_loop_run(main_loop); // 进入主循环
}
// 接收请求
static gboolean receive_text(ComGdbusDemo *object, GDBusMethodInvocation *invocation, const gchar *input, gpointer user_data) {
g_print("Receive -> %s\n", input);
com_gdbus_demo_complete_show_data(object, invocation, "OK"); // 返回数据
sleep(2); // 模拟处理
com_gdbus_demo_emit_complete(skeleton, "Process complete"); // 发送完成信号
g_print("Complete signal sent.\n");
return true; // 请求处理成功
}
// 如果无法建立与总线的连接会调用 name_lost_handler()
// 如果无法获取 bus-name,会先调用 bus_acquired_handler(),再调用 name_lost_handler()
// 如果已获得 bus-name ,会先调用 bus_acquired_handler(),再调用 name_acquired_handler()
// GDBus Acquired 回调
static void gdbus_acquired_callback(GDBusConnection *callback_connection, const gchar *name, gpointer user_data) {
GError *error = NULL;
skeleton = com_gdbus_demo_skeleton_new();
g_signal_connect(skeleton, "handle-show-data", G_CALLBACK(receive_text), NULL); // 设置对象接口
g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(skeleton), callback_connection,
"/com/gdbus/object", &error); // 绑定到对象上
if (error != 0) {
g_print("Failed to export object: %s.\n", error->message);
g_error_free(error);
g_main_loop_quit(main_loop); // 退出主循环
return;
}
g_print("Skeleton load successfully.\n");
}
// GDBus Name Acquired 回调
static void gdbus_name_acquired_callback(GDBusConnection *callback_connection, const gchar *name, gpointer user_data) {
g_print("Acquired bus-name success.\n");
}
// GDBus Name Lost 回调
static void gdbus_name_lost_callback(GDBusConnection *callback_connection, const gchar *name, gpointer user_data) {
g_print("Name lost error: Failed to get bus-name.\n");
g_main_loop_quit(main_loop); // 退出主循环
}
// 初始化DBus连接
void init_dbus_server() {
main_loop = g_main_loop_new(NULL, FALSE); // 创建主循环对象
// 申请 bus-name 并将结果给到回调函数
g_bus_own_name(G_BUS_TYPE_SESSION, "com.gdbus.demo", G_BUS_NAME_OWNER_FLAGS_NONE,
&gdbus_acquired_callback, &gdbus_name_acquired_callback,
&gdbus_name_lost_callback, NULL, NULL);
}
int main() {
pthread_t tid;
init_dbus_server(); // 初始化DBus
pthread_create(&tid, NULL, start_main_loop, NULL); // 创建线程 进入主循环
for (;;) {} // 死循环
}
Loading…
Cancel
Save