GDBus之方法调用

下一篇: GDBus之信号使用
本篇涉及到的知识:
1.dbus Method的同步与异步使用
2.dbus Method的参数如何传递
3.dbus Method的返回值如何处理

method-test.c 文件

#include <stdio.h>
#include <signal.h>
#include <glib.h>	//提供GMainLoop类型定义、g_new0()函数声明
#include <gio/gio.h>	//提供GDBusConnection类型定义、g_dbus_...等函数声明

const char beijing_dbus_server_name[] = {"world.china.beijing.test"}; 		//dbus服务名
const char beijing_dbus_interface_name[] = {"world.china.beijing"};             //dbus接口名
const char beijing_dbus_object_name[] = {"/world/china/beijing"};               //dbus对象名
const char property_interface_name[] = {"org.freedesktop.DBus.Properties"};     //property接口名

GMainLoop *loop = NULL;
GDBusConnection *global_connection = NULL;

//函数声明
void dbus_method_call_async_set_population();
void dbus_method_call_sync_get_all_district();
void dbus_method_call_async_set_population_callback(GObject* object, GAsyncResult* res, gpointer data);
void signal_sigint_handler();

int main(){
	signal(SIGINT, signal_sigint_handler);
	loop = g_main_loop_new(NULL,FALSE);		//创建主循环,NULL表示没有上下文,FALSE表示不立即运行

	//1. 使用同步方式获取session dbus连接
	global_connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
	//2. 异步调用dbus Method
	dbus_method_call_async_set_population();
	//3. 同步调用dbus Method
	dbus_method_call_sync_get_all_district();

	g_main_loop_run(loop);				//运行主循环

	return 0;
}

/** 异步调用dbus方法示例、参数传递示例
 *  调用beijing dbus服务的SetPopulation方法
 */
void dbus_method_call_async_set_population(){
	GVariant *parameters = g_variant_new("(d)", 1.23);	//SetPopulation函数接受一个Double类型的参数
	const GVariantType *reply_type = G_VARIANT_TYPE("()");	//SetPopulation函数无返回值
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE;
	int timeout = 5000;					//超时5秒自动退出

	//dbus Method异步调用示例
	g_dbus_connection_call(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, beijing_dbus_interface_name,
			"SetPopulation", parameters, reply_type, flags, timeout, NULL,
			(GAsyncReadyCallback)dbus_method_call_async_set_population_callback, NULL);
}

/** 同步调用beijing dbus的GetAllDistrict方法
 *  演示如何处理dbus Method返回的复杂类型
 */
void dbus_method_call_sync_get_all_district(){
	GError *error = NULL;
	GVariant *result = NULL;
	GVariant* parameters = NULL;				//该dbus Method不需要参数(参数为NULL)
	const GVariantType *reply_type = G_VARIANT_TYPE("(as)");//该dbus Method返回值为一个字符串数组(a表示数组 s表示是字符串)
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NONE;
	int timeout = 5000;					//超时5秒自动退出
	result = g_dbus_connection_call_sync(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, beijing_dbus_interface_name,
			"GetAllDistrict", parameters, reply_type, flags, timeout, NULL, &error);

	if(error){
		printf("[dbus-method-call-sync]:%s\n",error->message);
		g_error_free(error);
		error = NULL;
		return;
	}

	//处理方法返回值
	int index = 0;
	char* tmp  = NULL;
	char **all_districts = NULL;
	g_autoptr(GVariantIter) iter = NULL;	//智能指针
	
	all_districts = g_new0(char*, 17);	//北京16个区,我们分配17个地址
	g_variant_get(result, "(as)", &iter);	//获取指向dbus Method返回值的迭代器

	/*&s 表示直接使用已有数据内存的地址,不需要额外分配内存*/
	while(g_variant_iter_loop(iter, "&s", &tmp))//如果"&s"替换为"s"则会乱码
		all_districts[index++] = tmp;

	//查看dbus Method通信的结果
	for(index = 0; all_districts[index]; ++index){
		printf("%s ",all_districts[index]);
	}
	printf("\n");
	g_free(all_districts);			//释放二维数组内存

	g_variant_unref(result);		//释放变体类型
	result = NULL;
}

/** 异步调用dbus Method的回调函数
 *  用于查看Method是否调用成功,失败了可以查看error->message错误信息
 *  也可增加其他的业务处理逻辑
 */
void dbus_method_call_async_set_population_callback(GObject* object, GAsyncResult* res, gpointer data){
	GError* error = NULL;
	GVariant *value = NULL;

	printf("[dbus-method-async-call] call setPopulation finished\n");
	value = g_dbus_connection_call_finish(global_connection, res, &error);
	if(error){
		printf("[dbus-close] %s\n",error->message);
		g_error_free(error);
	}
	if(value){
		g_variant_unref(value);
		return;
	}
}

/** 处理linux操作系统的SIGINT信号(Ctl+C组合键)
 *  用于退出主循环,释放内存,退出程序
 */
void signal_sigint_handler(){
	GError *error = NULL;
	if(global_connection && G_IS_DBUS_CONNECTION(global_connection)){
		g_dbus_connection_close_sync(global_connection,NULL,&error);
		global_connection = NULL;
	}
	if(error){
		printf("[dbus-close] %s\n",error->message);
		g_error_free(error);
	}

	if(loop){
		g_main_loop_quit(loop);
		g_main_loop_unref(loop);
		loop = NULL;
	}
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值