在BlueZ中调用多参数方法时遇GLib断言失败问题求助
问题分析与解决
错误根源
你遇到的g_utf8_validate断言失败,核心原因是错误使用了g_variant_new的参数格式:
在构造CreateSession方法的参数时,g_variant_new("(s{sv})")中的s类型要求直接传入UTF-8编码的C字符串,但你却传入了g_variant_new_string()返回的GVariant*对象。GLib会把这个指针当作字符串地址去验证UTF-8格式,显然不符合要求,因此触发两次断言失败。
修正后的代码
将g_variant_new的第一个参数直接替换为原始字符串,同时补充资源释放逻辑避免内存泄漏:
GVariantBuilder *b; GVariant *obex_dict; GError *error = NULL; b = g_variant_builder_new(G_VARIANT_TYPE("a{sv}")); g_variant_builder_add(b, "{sv}", "Target", g_variant_new_string("ftp")); obex_dict = g_variant_builder_end(b); // 释放builder资源 g_variant_builder_unref(b); g_dbus_connection_call_sync( conn, BLUEZ_ORG, "/org/bluez/obex", "org.bluez.obex.Client1", "CreateSession", // 直接传入C字符串,而非GVariant对象 g_variant_new("(s{sv})", "/org/bluez/hci0/dev_5C_87_30_66_F4_35", obex_dict), NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); // 释放variant资源 g_variant_unref(obex_dict); if (error != NULL) { // 用g_warning替代g_error避免程序直接终止,同时释放错误对象 g_warning("CreateSession failed: %s", error->message); g_error_free(error); }
额外注意事项
g_variant_new的格式字符串与参数类型必须严格匹配:s对应const gchar*,v对应GVariant*,a{sv}对应构建好的字典变体。- 所有
GVariant和GVariantBuilder对象使用后必须调用对应的unref方法释放,防止内存泄漏。 g_error()会直接终止程序,建议在生产代码中改用更温和的错误处理逻辑,并记得释放GError对象。
内容的提问来源于stack exchange,提问作者Nima Behmanesh
相关产品推荐
相关产品推荐

