quickstart.md 4.6 KB

RyanJson 快速上手(RT-Thread/C)

范围

  • 本文提供“最小可跑通”的公开 API 路径。
  • 完整业务模板见 integrationTemplate.md
  • 平台差异实现见 rtThreadExamples.md
  • 失败所有权细则见 ownershipAndErrors.md

入口条件(必须)

  1. 任何 Json API 前先完成 RyanJsonInitHooks
  2. 回答或示例中标明宏前提:
    • RyanJsonStrictObjectKeyCheck
    • RyanJsonDefaultAddAtHead
  3. 每条失败分支都要显式释放(RyanJsonDelete / RyanJsonFree)。

示例 1:初始化 hooks(一次性)

#include <stdlib.h>
#include "RyanJson.h"

static RyanJsonBool_e appEnsureJsonHooks(void)
{
    static RyanJsonBool_e inited = RyanJsonFalse;
    if (RyanJsonTrue == inited) { return RyanJsonTrue; }

    inited = RyanJsonInitHooks(malloc, free, realloc);
    return inited;
}

示例 2:Parse + Get(安全读取)

#include <stdint.h>
#include "RyanJson.h"

static RyanJsonBool_e readAge(const char *jsonText, int32_t *outAge)
{
    RyanJson_t root = NULL;
    RyanJson_t ageItem = NULL;

    if ((NULL == jsonText) || (NULL == outAge)) { return RyanJsonFalse; }
    if (RyanJsonFalse == appEnsureJsonHooks()) { return RyanJsonFalse; }

    root = RyanJsonParse(jsonText);
    if (NULL == root) { return RyanJsonFalse; }

    ageItem = RyanJsonGetObjectByKey(root, "age");
    if ((NULL == ageItem) || (RyanJsonFalse == RyanJsonIsInt(ageItem)))
    {
        RyanJsonDelete(root);
        return RyanJsonFalse;
    }

    *outAge = RyanJsonGetIntValue(ageItem);
    RyanJsonDelete(root);
    return RyanJsonTrue;
}

示例 3:Create + Add + PrintPreallocated(非格式化输出)

#include <stdint.h>
#include "RyanJson.h"

static RyanJsonBool_e buildReport(char *out, uint32_t outCap, uint32_t *outLen)
{
    RyanJson_t root = NULL;

    if ((NULL == out) || (NULL == outLen) || (0U == outCap)) { return RyanJsonFalse; }

    root = RyanJsonCreateObject();
    if (NULL == root) { return RyanJsonFalse; }

    if ((RyanJsonFalse == RyanJsonAddStringToObject(root, "name", "ryan")) ||
        (RyanJsonFalse == RyanJsonAddIntToObject(root, "age", 18)))
    {
        RyanJsonDelete(root);
        return RyanJsonFalse;
    }

    if (NULL == RyanJsonPrintPreallocated(root, out, outCap, RyanJsonFalse, outLen))
    {
        RyanJsonDelete(root);
        return RyanJsonFalse;
    }

    RyanJsonDelete(root);
    return RyanJsonTrue;
}

示例 4:Replace 跨类型切换(失败不消费 newItem)

#include "RyanJson.h"

static RyanJsonBool_e replaceFreqAsObject(RyanJson_t root)
{
    RyanJson_t newFreq = NULL;

    if (NULL == root) { return RyanJsonFalse; }

    newFreq = RyanJsonCreateObject();
    if (NULL == newFreq) { return RyanJsonFalse; }
    if (RyanJsonFalse == RyanJsonIsDetachedItem(newFreq))
    {
        RyanJsonDelete(newFreq);
        return RyanJsonFalse;
    }

    if ((RyanJsonFalse == RyanJsonAddIntToObject(newFreq, "value", 100)) ||
        (RyanJsonFalse == RyanJsonAddStringToObject(newFreq, "unit", "Hz")))
    {
        RyanJsonDelete(newFreq);
        return RyanJsonFalse;
    }

    if (RyanJsonFalse == RyanJsonReplaceByKey(root, "freq", newFreq))
    {
        RyanJsonDelete(newFreq); // Replace 失败:调用方负责释放
        return RyanJsonFalse;
    }

    return RyanJsonTrue;
}

示例 5:Detach 后重挂或释放

#include "RyanJson.h"

static RyanJsonBool_e movePayload(RyanJson_t src, RyanJson_t dst)
{
    RyanJson_t detached = NULL;

    if ((NULL == src) || (NULL == dst)) { return RyanJsonFalse; }

    detached = RyanJsonDetachByKey(src, "payload");
    if (NULL == detached) { return RyanJsonFalse; }

    if (RyanJsonFalse == RyanJsonAddItemToObject(dst, "payload", detached))
    {
        // 当前实现下,对游离节点 AddItem 失败路径由库侧清理;不要二次释放 detached
        return RyanJsonFalse;
    }

    return RyanJsonTrue;
}

最小检查单

  1. hooks 初始化是否先于 Parse/Create。
  2. Get 前是否判空 + 判型。
  3. Replace 失败后是否由调用方处理 newItem
  4. 动态打印返回值是否配对 RyanJsonFree
  5. 退出分支是否都做了 RyanJsonDelete

依据(仓库内)

  • RyanJson/RyanJson.cRyanJsonInitHooksRyanJsonDelete
  • RyanJson/RyanJsonItem.cRyanJsonReplaceByKeyRyanJsonDetachByKeyRyanJsonAddItemToObject
  • test/unityTest/cases/core/testReplace.c:Replace 失败不消费 item
  • test/unityTest/cases/core/testDetach.ctest/unityTest/cases/core/testCreate.c:Detach/AddItem 失败路径
  • test/unityTest/cases/utils/testPrint.c:非格式化打印与 preallocated 边界