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

字符串与整数模板冲突及json-glib生成JSON的字符处理问题

解决json-glib生成多类型JSON时的字符串处理问题

看起来你在使用json-glib构建包含多类型value字段的JSON结构时,卡在了std::string的c_str()和char*类型的处理上。我来帮你梳理下完整的解决方案,同时完善你现有的类型分支逻辑:

核心问题分析

你现有的代码已经覆盖了整数和布尔类型,但缺少字符串(std::string/const char*/char*)和浮点数的处理逻辑。其中字符串类型的关键在于:

  • json-glib的json_builder_add_string_value接受const gchar*(本质等价于const char*)作为参数
  • std::string的c_str()返回临时的const char*,但json-glib会内部复制字符串内容,只要调用API时字符串对象未被销毁/修改就不会有悬空指针问题
  • char需要强转为const char才能匹配API参数类型

完整的泛型处理代码

下面是一个覆盖所有你提到的类型的泛型函数,用C++17的if constexpr实现编译期类型分支,避免运行时开销:

#include <json-glib/json-glib.h>
#include <type_traits>
#include <string>

// 泛型函数:向JsonBuilder添加对应类型的value
bool add_json_value(JsonBuilder* builder, const auto& tagValue) {
    using T = std::decay_t<decltype(tagValue)>;

    // 处理布尔类型
    if constexpr (std::is_same_v<T, bool>) {
        if (!json_builder_add_boolean_value(builder, tagValue)) {
            // 这里可以添加你的错误处理逻辑,比如设置返回信息
            return false;
        }
    }
    // 处理整数类型(排除布尔)
    else if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) {
        if (!json_builder_add_int_value(builder, static_cast<gint64>(tagValue))) {
            return false;
        }
    }
    // 处理浮点数类型
    else if constexpr (std::is_floating_point_v<T>) {
        if (!json_builder_add_double_value(builder, static_cast<gdouble>(tagValue))) {
            return false;
        }
    }
    // 处理std::string类型
    else if constexpr (std::is_same_v<T, std::string>) {
        // c_str()返回const char*,直接传入即可,json-glib会内部复制内容
        if (!json_builder_add_string_value(builder, tagValue.c_str())) {
            return false;
        }
    }
    // 处理const char*类型
    else if constexpr (std::is_same_v<T, const char*>) {
        if (!json_builder_add_string_value(builder, tagValue)) {
            return false;
        }
    }
    // 处理char*类型:强转为const char*匹配API参数
    else if constexpr (std::is_same_v<T, char*>) {
        if (!json_builder_add_string_value(builder, static_cast<const char*>(tagValue))) {
            return false;
        }
    }
    // 不支持的类型分支
    else {
        // 可以添加不支持类型的错误提示
        return false;
    }

    return true;
}

关键注意事项

  1. c_str()的生命周期:只要在调用json_builder_add_string_value时,std::string对象还处于存活状态(未被销毁或修改),c_str()的指针就是有效的,无需担心悬空问题——因为json-glib会把字符串内容复制到内部结构中。
  2. 类型匹配:char类型必须强转为const char,否则会触发编译错误(json-glib的API不接受非const的char*)。
  3. json-glib初始化:务必在程序启动时调用json_init(),结束时调用json_cleanup(),否则API可能无法正常工作。

使用示例(构建完整的JSON对象)

int main() {
    // 初始化json-glib
    json_init();

    JsonBuilder* builder = json_builder_new();
    json_builder_begin_object(builder);

    // 添加id字段(固定为std::string类型)
    json_builder_set_member_name(builder, "id");
    std::string user_id = "rest_api_001";
    if (!add_json_value(builder, user_id)) {
        g_printerr("Failed to add id field\n");
        goto cleanup;
    }

    // 测试添加字符串类型的value
    json_builder_set_member_name(builder, "value");
    std::string str_value = "Hello JSON-GLib";
    if (!add_json_value(builder, str_value)) {
        g_printerr("Failed to add string value\n");
        goto cleanup;
    }

    // 你也可以测试其他类型:
    // json_builder_set_member_name(builder, "value");
    // bool bool_val = true;
    // add_json_value(builder, bool_val);

    json_builder_end_object(builder);

    // 生成并打印JSON字符串
    JsonNode* root = json_builder_get_root(builder);
    gchar* json_str = json_to_string(root, TRUE);
    g_print("Generated JSON:\n%s\n", json_str);

cleanup:
    // 释放资源
    if (json_str) g_free(json_str);
    if (root) json_node_unref(root);
    g_object_unref(builder);
    json_cleanup();
    return 0;
}

内容的提问来源于stack exchange,提问作者Dark Sorrow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:22:27