为什么我收到错误“解析 JSON 时出错:[json.exception.type_error.302] 类型必须是数组,但是是对象”

问题描述 投票:0回答:1

以下函数(或其一部分,我只会添加与问题相关的部分)应该从

.json
文件加载我正在制作的简单游戏引擎的 UI 配置(这都是自定义的) 。我正在使用现代 C++ 的 Nlohmann JSON 库。

void UIManager::loadUiConfig(SceneManager& sceneManager){
    std::ifstream uiFile("..\\resources\\ui\\ui.json");
    if(!uiFile.is_open()){
        std::cerr << "Failed to load ui configuration file" << std::endl;
        exit(EXIT_FAILURE);
    }

    json uiConfig;
    try{
        uiFile >> uiConfig;
    }catch(const json::parse_error& e){
        std::cerr << e.what() << std::endl;
        exit(EXIT_FAILURE);
    }

    StructScenes scenesData;
    try{
        if(!uiConfig.contains("scenes")) throw std::runtime_error("scenes is not found");
        if(uiConfig["scenes"].is_null()) throw std::runtime_error("scenes is empty/null");
        scenesData = uiConfig.template get<StructScenes>();

    } catch (const std::runtime_error& e) {
        std::cerr << "Runtime Error: " << e.what() << std::endl;
        exit(EXIT_FAILURE);
    }catch(const json::type_error& e){
        std::cerr << "Error parsing JSON: " << e.what() << std::endl;
        exit(EXIT_FAILURE);
    }
    //rest of function
}

这些是我定义的用于保存

.json
文件中的数据的结构:

#ifndef SERIALIZER_CLASS_H
#define SERIALIZER_CLASS_H

#include <glad/glad.h>
#include <vector>
#include <string>
#include <unordered_map>
#include <EventHandler/EventType.h>
#include <Json/json.hpp>
#include <ui/ui.h>

struct StructAppearance{
    GLfloat posX, posY;
    GLfloat width, height;
    GLfloat color[4];
    GLfloat texturePosX, texturePosY;
    std::string textureImagePath;
    int renderType;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructAppearance, posX, posY, width, height, color, texturePosX, texturePosY, textureImagePath, renderType);
};

struct StructButton{

    std::string name;
    std::vector<std::pair<EventType, std::string>> events;
    StructAppearance appearance;
    Shapes shape;
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};

struct StructScene {
    std::string name;
    std::vector<StructButton> sceneMembers;
    std::string vertexShaderPath;
    std::string fragmentShaderPath;
    GLfloat backgroundColor[4];
    int posSize, colorSize, texSize;

    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructScene, sceneMembers, vertexShaderPath, fragmentShaderPath, backgroundColor, posSize, colorSize, texSize);
};

struct StructScenes{
    std::vector<StructScene> scenes;
    NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructScenes, scenes);
};

#endif

入口结构(或根结构)是

StructScenes
,它只包含所有可用场景的
std::vector<StructScene>
(这只是我在游戏中创建菜单的方法)。

问题出在我想要将

.json
数据反序列化到
StructScenes
的部分。它一直显示此错误:

解析 JSON 时出错:[json.exception.type_error.302] 类型必须是数组,但却是对象

具体来说,错误发生在这一行:

scenesData = uiConfig.template get<StructScenes>();

我尝试直接制作

std::vector<StructScene>
,但同样的问题发生在我收到上述错误的地方,而不是实际创建场景并用相应的按钮填充它们。

编辑:因为人们要求 ui.json 文件,这是我正在使用的示例:

{
  "scenes": [
    {
      "name": "Main Menu",
      "sceneMembers": [
        {
          "name": "Play",
          "events": [
            {
              "type": "onclick",
              "action": "settings"
            }
          ],
          "appearance": {
            "posX": -0.9,
            "posY": 0.1,
            "width": 0.4,
            "height": 0.3,
            "color": [0, 0, 0, 0],
            "texturePosX": 0,
            "texturePosY": 0,
            "textureImagePath": "..\\resources\\textures\\play.png",
            "renderType": 1
          },
          "shape": "rectangle"
        }
      ],
      "vertexShaderPath": "..\\resources\\Shaders\\default.vert",
      "fragmentShaderPath": "..\\resources\\Shaders\\default.frag",
      "backgroundColor": [1.0, 1.0, 1.0, 1.0],
      "posSize": 2,
      "colorSize": 4,
      "texSize": 2
    }
  ]
}
c++ json nlohmann-json
1个回答
0
投票

根据您提供的 json 文件,

events
字段应该是一个对象数组

"events": [
  {
    "type": "onclick",
    "action": "settings"
  }
],

因此该结构体的

events
成员不正确

struct StructButton {
  std::string name;
  std::vector<std::pair<EventType, std::string>> events;
  StructAppearance appearance;
  Shapes shape;
  NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};

它应该是另一个结构,它将是一个 json 对象

struct StructEvent {
  std::string type;
  std::string action;
};

然后您将更新 Button 成员

struct StructButton {
  std::string name;
  std::vector<StructEvent> events;
  StructAppearance appearance;
  Shapes shape;
  NLOHMANN_DEFINE_TYPE_INTRUSIVE(StructButton, name, events, appearance, shape);
};
© www.soinside.com 2019 - 2024. All rights reserved.