You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 05:05:55