GDBus之属性使用

本篇涉及的知识:
1.dbus Property的set与get操作、参数传递
2.dbus PropertiesChanged信号如何捕获

property-test.c 文件

#include <glib.h>
#include <gio/gio.h>
#include <stdio.h>

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;

const char property_operation_name[] = {"Population"};				//围绕该属性做读写操作

//函数声明
void property_get_operation_sync();
void property_set_operation_sync();
void property_get_operation_async();
void property_get_all_operation_async();
void property_changed_listen();

/** 测试目标:同步连接dbus、同步设置dbus Property、异步设置/获取dbus Property
 *            监听dbus Property改变的信号
 */
int main(){
	//1. 创建主循环
	loop = g_main_loop_new(NULL,FALSE);

	//2. 获取session dbus connection (因为我们的服务是创建在session dbus总线的,而不是system dbus总线)
	global_connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);

	//3. 同步方式获取属性初始值
	property_get_operation_sync();

	//4. 监控dbus服务的属性值改变
	property_changed_listen();

	//5. 同步方式设置属性值
	property_set_operation_sync();

	//6. 异步方式获取修改后的属性值
	property_get_operation_async();

	//7. 异步方式获取dbus服务的所有属性值
	property_get_all_operation_async();

	//8. 启动主循环
	g_main_loop_run(loop);
	return 0;
}


//同步方法设置某个属性值
void property_set_operation_sync(){
	GVariant* result = NULL;
	GVariant* parameters = NULL;		//Set方法的参数
	const GVariantType *reply_type = NULL;	//Set函数的返回值类型为NULL;
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NO_AUTO_START;
	int timeout = 5000;			//超时5秒自动退出
	GError *error = NULL;			//捕捉错误信息

	//Set函数有三个参数,类型分别是String, String, Variant
	parameters = g_variant_new("(ssv)", beijing_dbus_interface_name, property_operation_name, g_variant_new_double(10.20));	//设置Beijing的popution属性值为10.20,不需要释放
	result = g_dbus_connection_call_sync(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, property_interface_name,
				"Set", parameters, reply_type, flags, timeout, NULL, &error);

	if(error){
		printf("[property-set-sync] %s\n",error->message);
		g_error_free(error);
		return;
	}

	//释放内存
	if(result){
		g_variant_unref(result);
		result = NULL;
	}
}

//同步方法获取某个属性值
void property_get_operation_sync(){
	GVariant* result = NULL;
	GVariant* parameters = NULL;		//Get方法的参数
	const GVariantType *reply_type = G_VARIANT_TYPE("(v)");	//Get函数的返回值类型为"(v)";
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NO_AUTO_START;
	int timeout = 5000;			//超时5秒自动退出
	GError *error = NULL;			//捕捉错误信息
	double property_value = -1;


	//Get方法需要2个参数:接口名、属性名
	parameters = g_variant_new("(ss)", beijing_dbus_interface_name, property_operation_name);		//获取Beijing的population属性值
	result = g_dbus_connection_call_sync(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, property_interface_name,
				"Get", parameters, reply_type, flags, timeout, NULL, &error);

	if(error){
		printf("[property-get-sync] %s\n",error->message);
		g_error_free(error);
		return;
	}

	if(result){
		GVariant *value = NULL;
		g_variant_get(result,"(v)", &value);		//Get函数返回值是变体Variant类型
		property_value = g_variant_get_double(value);	//将变体Variant类型转为Double类型
		g_variant_unref(value);
		g_variant_unref(result);
		result = NULL;
	}
	printf("[property-get-sync] population=%lf\n",property_value);
}

/** 异步获取某个属性值的回调函数、演示Get函数的返回值处理方式
 */
void property_get_operation_async_callback(GObject* object, GAsyncResult *ret, gpointer data){
	GError *error = NULL;
	double property_value = -1;
	GVariant* result = NULL;

	result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), ret, &error);
	if(error){
		printf("[property-get-async] %s\n",error->message);
		g_error_free(error);
		return;
	}

	if(result){
		GVariant *value = NULL;
		g_variant_get(result,"(v)", &value);		//Get函数返回值是Variant
		property_value = g_variant_get_double(value);	//Variant转Double
		g_variant_unref(value);
		g_variant_unref(result);
		result = NULL;
	}
	printf("[property-get-async] population=%lf\n",property_value);
}

/** 异步获取某个属性值、演示Get函数的参数以及用法
 */
void property_get_operation_async(){
	GVariant* parameters = NULL;
	const GVariantType *reply_type = G_VARIANT_TYPE("(v)");	//Get函数的返回值类型为"(v)";
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NO_AUTO_START;
	int timeout = 5000;			//超时5秒自动退出

	parameters = g_variant_new("(ss)", beijing_dbus_interface_name, property_operation_name);
	g_dbus_connection_call(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, property_interface_name,
			"Get", parameters, reply_type, flags, timeout, NULL, property_get_operation_async_callback, NULL);
}

/** 异步获取所有属性值的方法的回调函数、演示GetAll函数的返回值用法
 */
void property_get_all_operation_async_callback(GObject *object, GAsyncResult* ret, gpointer data){
	GError *error = NULL;
	GVariant* result = NULL;
	GVariantIter *iter = NULL;		//迭代器,用于遍历循环GetAll函数的返回值
	const char* key;
	GVariant *value;

	result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), ret, &error);
	if(error){
		printf("[property-get-all-async] %s\n",error->message);
		g_error_free(error);
		return;
	}

	g_variant_get(result, "(a{sv})", &iter);

	//轮询打印Dict里的每个键值对
	while(g_variant_iter_loop(iter, "{&sv}", &key, &value)){
		if(g_variant_is_of_type(value, G_VARIANT_TYPE("d"))){
			printf("<key,value> = <%s,%lf>\n",key, g_variant_get_double(value));
		}else{
			printf("<key,value> = <%s,%s>\n",key, g_variant_get_string(value, NULL));
		}
	}

	//释放内存
	g_variant_iter_free(iter);
	g_variant_unref(result);
}

/** 异步查询dbus服务的对象的所有属性值、演示GetAll函数的参数以及用法
 */
void property_get_all_operation_async(){
	GVariant* parameters = NULL;
	const GVariantType *reply_type = G_VARIANT_TYPE("(a{sv})");	//Get函数的返回值类型为"Dict of {String,Variant}";
	GDBusCallFlags flags = G_DBUS_CALL_FLAGS_NO_AUTO_START;
	int timeout = 5000;			//超时5秒自动退出

	parameters = g_variant_new("(s)", beijing_dbus_interface_name);	//GetAll函数只有一个参数: dbus接口名
	g_dbus_connection_call(global_connection, beijing_dbus_server_name, beijing_dbus_object_name, property_interface_name,
			"GetAll", parameters, reply_type, flags, timeout, NULL, property_get_all_operation_async_callback, NULL);
}

/** 监听属性改变的回调函数、获取发生改变的具体属性名
 */
void property_changed_callback (GDBusConnection *connection,const gchar *sender_name,const gchar *object_path,const gchar *interface_name,
                        const gchar *signal_name,GVariant *parameters, gpointer data){
	GVariantIter iter;
	const char *key = NULL;
	GVariant *props, *value;

	//NULL 对应 s
	//props 对应 @a{sv}
	//NULL 对应 *
	g_variant_get(parameters, "(s@a{sv}*)", NULL, &props, NULL);
	g_variant_iter_init(&iter, props);
	while(g_variant_iter_loop(&iter, "{sv}", &key, &value)){
		printf("[property-changed] %s had changed!\n", key);
	}

	g_variant_unref(props);
}

/** 监控属性值改变
 */
void property_changed_listen(){
	const char* unique_name = NULL;

	//unique_name = g_dbus_connection_get_unique_name(global_connection);//这种方式获取到的UniqueName不可用,因为它无法捕捉到信号
	//g_dbus_connection_signal_subscribe(global_connection, unique_name, property_interface_name,
	g_dbus_connection_signal_subscribe(global_connection, NULL, property_interface_name,
					"PropertiesChanged", beijing_dbus_object_name, beijing_dbus_interface_name,
					G_DBUS_SIGNAL_FLAGS_NONE, (GDBusSignalCallback)property_changed_callback,
					NULL, NULL);
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值