jansson库使用

12 篇文章 5 订阅

jansson库使用

1. 将结构体转化为json字符串(解决jansson转化字符串失败)

写了一个转换测试程序,发现运行个20多次后,就一直转换失败了。先后测试free(),json_object_clear() 和 json_decref()。发现只有json_decref()这个好使。估计是内存泄露导致的。

uint32_t mydata_oildrop_item_to_json(mydata_oildrop_item_t *item, char *buff, size_t len)
{
    JSON_NULL_PTR_ASSERT(item);

    json_t *root = NULL;
	char *out = NULL;
	size_t out_len = 0;
	
    root = json_pack("{s:i, s:i, s:i, s:i}", "effective", item->effective, "oil_drop_reason", item->oil_drop_reason, \
                                            "oil_drop_quantity", item->oil_drop_quantity, "timestamp", item->timestamp);
    if (root == NULL)
    {
        return NRF_ERROR_INVALID_DATA;
    }

    out = json_dumps(root, JSON_ENCODE_ANY);
	out_len = strlen(out);
	if (out_len >= len)
	{
		NRF_NUS_LOG_INFO("Buff is too small. Value: %d  Need: %d", len, out_len + 1);
		// free(root);
		// json_object_clear(root);
		json_decref(root);
		free(out);
		return NRF_ERROR_INVALID_LENGTH;
	}
	
	NRF_NUS_LOG_INFO("%s", buff);
	strncpy(buff, out, out_len);
    // free(root);
	// json_object_clear(root);
	json_decref(root);
	free(out);

    return NRF_SUCCESS;
}

在创建或者获取到一个json对象时,引用计数器会自增。我们在释放json对象所占用的内存时,需要通过json_decref()减小引用计数器的值,当引用计数器的值为0时,jansson库会释放掉json对象所占用的堆内存。

比如我通过json_object()创建一个json对象obj_1,然后通过json_array_append()将创建的这个对象0bj_1追加到另外一个json数组array_1中。当我们通过json_decref()释放掉数组对象array_1时,我们创建的json对象obj_1并不会被释放掉。

原因是:当我们使用json_array_append()时,obj_1的引用计数器会自增1,这个时候obj_1的引用计数器值为2,当我们释放掉array_1时,obj_1的引用计数器自减1,这个时候obj_1引用计数器值为1,obj_1占用的堆内存是没有释放掉的。反复进行这样的操作会导致,会导致堆内存泄露,最后没有办法申请内存,导致json库的API失败,或者导致程序跑飞。

另外,使用json_object_set_new(obj_1, obj_2)这类型的接口,是将对象obj_2添加到对象obj_1中,不是简单的指针赋值,而是重新创建,并且这个接口会使obj_2的引用计数器自减1,如果没有其它的json对象使用obj_2,即obj_2的引用计数器为1,则调用这个接口后,ojb_2空间将释放。

json_pack()接口转换失败。原因可能格式定义问题,比如我定义的格式是"{si,si}“,而我给的参数是(7,7),即json_pack(”{si,si}", 7, 7),这种情况会导致转换失败。

另外的,就是堆空间大小不够。比如我需要转化很大的一个json对象,此时是需要很大的内存的,堆内存小于需要的内存空间,也会导致转换失败。

    for (uint8_t i = 0; i < 10; i++)
    {
        ponit = json_pack("{s:[iiiiiiiiii],s:[iiiiiiiiii]}",
                          "temp", oil_drop_lines.lines[0].ponits[0].temp, oil_drop_lines.lines[0].ponits[1].temp,
                          oil_drop_lines.lines[0].ponits[2].temp, oil_drop_lines.lines[0].ponits[3].temp,
                          oil_drop_lines.lines[0].ponits[4].temp, oil_drop_lines.lines[0].ponits[5].temp,
                          oil_drop_lines.lines[0].ponits[6].temp, oil_drop_lines.lines[0].ponits[7].temp,
                          oil_drop_lines.lines[0].ponits[8].temp, oil_drop_lines.lines[0].ponits[9].temp,
                          "quanlity", oil_drop_lines.lines[0].ponits[0].quantity, oil_drop_lines.lines[0].ponits[1].quantity,
                          oil_drop_lines.lines[0].ponits[2].quantity, oil_drop_lines.lines[0].ponits[3].quantity,
                          oil_drop_lines.lines[0].ponits[4].quantity, oil_drop_lines.lines[0].ponits[5].quantity,
                          oil_drop_lines.lines[0].ponits[6].quantity, oil_drop_lines.lines[0].ponits[7].quantity,
                          oil_drop_lines.lines[0].ponits[8].quantity, oil_drop_lines.lines[0].ponits[9].quantity);

        if (ponit == NULL)
        {
            NRF_NUS_LOG_INFO("ponit null.");
            goto json_error;
        }

        line = json_pack("{si}", "oil_type", oil_drop_lines.lines[i].oil_type);
        if (line == NULL)
        {
            NRF_NUS_LOG_INFO("line null.");
            goto json_error;
        }

        ret = json_object_set(line, "ponits", ponit);

        if (ret != 0)
        {
            NRF_NUS_LOG_INFO("json_object_set_new.");
            goto json_error;
        }

        ret = json_array_append(lines, line);

        if (ret != 0)
        {
            NRF_NUS_LOG_INFO("json_array_append.");
            goto json_error;
        }

        json_decref(ponit);
        json_decref(line);
    }

此时,修改.s文件里面堆空间大小,让这个足够大即可。Nordic平台修改堆空间需要在如下窗口中设置。
在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值