Search code examples
c++msgpack

How to extract value from msgpack::map using msgpack-c C++ interface


I'm super confused about how to extract values from a map object unpacked using msgpack-c's C++ interface. I naively assumed I could do something like this:

msgpack::object_handle oh = msgpack::unpack(rbb_buf, bytes_recvd);
msgpack::object obj = oh.get();

if (oh.get().type == msgpack::type::MAP) {
  auto map = *obj.via.map.ptr;
  auto cps = map["status"];  // <-- This line does not compile
}

But the compiler complains:

/home/evadeflow/projects/prm/csr_bridge/src/csr_bridge.cpp:97:25: error: no match for ‘operator[]’

I just need to get one integer value under the key "status" from the map. Can anybody explain how to do it?


Solution

  • Well, it's been over three weeks so I finally had to get this sorted yesterday. I must have used different search terms this time around because I found another answer on SO that unraveled the mystery for me.

    Long-story short, I was able to use msgpack::object::convert() to copy the MesagePack object into a std::map<std::string, msgpack::type::variant> that I could then manipulate:

    msgpack::object obj = oh.get();
    
    if (obj.type == msgpack::type::MAP) {
        std::map<std::string, msgpack::type::variant> data = obj.convert();
       ...
    }
    

    The msgpack::type::variant class has a bunch of member functions (is_bool(), is_string(), etc) for sussing out the underlying type, so it was easy to index into the keys of this map and pull out the data I needed. (Fortunately, the data structure I was parsing was only one-level deep, so I didn't need to resort to the more complicated approaches discussed in this answer.)