通过Boost ASIO发送对象时断言`IsObject()'失败

时间:2018-01-15 15:43:12

标签: c++ json boost-asio rapidjson

我正在使用RapidJSON通过Boost ASIO发送对象,我收到此错误消息:

./include/rapidjson/document.h:1233: rapidjson::GenericValue<Encoding, Allocator>::MemberIterator rapidjson::GenericValue<Encoding, Allocator>::FindMember(const rapidjson::GenericValue<Encoding, SourceAllocator>&) [with SourceAllocator = rapidjson::MemoryPoolAllocator<>; Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; rapidjson::GenericValue<Encoding, Allocator>::MemberIterator = rapidjson::GenericMemberIterator<false, rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator<> >]: Assertion `IsObject()' failed.

这是我放在rapidJson :: Document.Parse()

中的字符串
{ "rotation": "1.000000", "size": "1.000000", "collide": "100", "lifePoint": "5", "id": "1", "type": "1", "pos.x": "1.100000", "pos.y": "1.200000" }

我在本课程中使用我的document.Parse

class Data
{
public:
  Data(std::string data) {
    rapidjson::Document document;
    document.Parse(data.c_str());


    rotation_ = document["rotation"].GetFloat();
    size_ = document["size"].GetFloat();
    collide_ = document["collide"].GetInt();
    lifePoint_ = document["lifePoint"].GetInt();
    id_ = document["id"].GetInt();
    type_ = document["type"].GetInt();
    pos_.first = document["pos.x"].GetFloat();
    pos_.second = document["pos.y"].GetFloat();
  };

  ~Data(){};

  void print()
  {
     std::cout << rotation_ << " = rotation_" << std::endl;
    std::cout << size_ << " = size_" << std::endl;
    std::cout << collide_ << " = collide_" << std::endl;
    std::cout << lifePoint_ << " = lifePoint_" << std::endl;
    std::cout << id_ << " = id_" << std::endl;
    std::cout << type_ << " = type_" << std::endl;
    std::cout << pos_.first << " = pos_.x" << std::endl;
    std::cout << pos_.second << " = pos_.y" << std::endl;
  }

  std::string getJson() {

    std::string json("{ \"rotation\": \"" + std::to_string(rotation_) + "\", \"size\": \"" + std::to_string(size_) + "\", \"collide\": \"" + std::to_string(collide_) + "\", \"lifePoint\": \"" + std::to_string(lifePoint_) + "\", \"id\": \"" + std::to_string(id_) + "\", \"type\": \"" + std::to_string(type_) + "\", \"pos.x\": \"" + std::to_string(pos_.first) + "\", \"pos.y\": \"" + std::to_string(pos_.second) + "\" }");
    return json;
  };

private:
  //geometry
  std::pair<float, float> pos_;
  float rotation_ = 1;
  float size_ = 1;
  int collide_ = 0;

  //game
  int lifePoint_;
  int id_;
  int type_;
};

我在这里调用Data构造函数

void BoostClient::receivePacket()
{
  boost::array<char, 2048> recv_buf;
  udp::endpoint sender_endpoint;
  static_cast<udp::socket *>(socket_)->receive_from(
      boost::asio::buffer(recv_buf), sender_endpoint);

  std::cout << "received: " << std::string(recv_buf.data()) << std::endl;
  std::string json(recv_buf.data());
  Data data(json);
  data.print();
};

有人知道如何解决它吗?我已经验证了JSON语法,这已经足够了。

输出:

E�ived: { "rotation": "1.000000", "size": "1.000000", "collide": "100", "lifePoint": "5", "id": "1", "type": "1", "pos.x": "1.100000", "pos.y": "1.200000" }
client: ./include/rapidjson/document.h:1233: rapidjson::GenericValue<Encoding, Allocator>::MemberIterator rapidjson::GenericValue<Encoding, Allocator>::FindMember(const rapidjson::GenericValue<Encoding, SourceAllocator>&) [with SourceAllocator = rapidjson::MemoryPoolAllocator<>; Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; rapidjson::GenericValue<Encoding, Allocator>::MemberIterator = rapidjson::GenericMemberIterator<false, rapidjson::UTF8<>, rapidjson::MemoryPoolAllocator<> >]: Assertion `IsObject()' failed.
[1]    10410 abort (core dumped)  ./client 192.168.43.58 1300

2 个答案:

答案 0 :(得分:2)

您应该检查parse errors的解析返回值:

ParseResult ok = doc.Parse("[42]");
if (!ok) {
    fprintf(stderr, "JSON parse error: %s (%u)",
            GetParseError_En(ok.Code()), ok.Offset());
...

确保在发送数据时写入终止为零的字符串 - 应该类似于send(json_str.c_str(), json_str.length() + 1)

答案 1 :(得分:0)

您是否尝试过这样的价值?

rotation_ = std::stof(document["rotation"].GetString());
size_ = std::stof(document["size"].GetString());
collide_ = std::stoi(document["collide"].GetString());
lifePoint_ = std::stoi(document["lifePoint"].GetString());
id_ = std::stoi(document["id"].GetString());
type_ = std::stoi(document["type"].GetString());
pos_.first = std::stof(document["pos.x"].GetString());
pos_.second = std::stof(document["pos.y"].GetString());