I'm new to Cap'nProto, but am trying to use it as a replacement for structs in an existing project. I'm needing to serialize/deserialize obviously, but also just access the data within various programs. I'm having a very hard time keeping a MessageBuilder, Builder, and Reader in a class.
It would be nice if I could deserialize a CapnProto struct in one method/function, modify it in another, read it in a third, and serialize in a fourth. But I'm stuck turning a PackedFdMessadeReader into a MessageBuilder (I don't mind any few memcpy's needed), and also creating a Builder instance as a member variable.
I'm attaching my closest attempt at this. But it fails to print out the original data value -- I get a null string -- and it fails to write the modified value out.
Any suggestions?
Topher
mystruct.capnp:
@0xed859a09d409be91;
struct MyStruct {
foo @0 :Text;
}
main.cpp:
#include <string>
#include <iostream>
#include <capnp/message.h>
#include <capnp/serialize-packed.h>
#include "mystruct.capnp.h"
class MyClass {
private:
capnp::MallocMessageBuilder m_message; // Or capnp::MessageBuilder *m_message maybe
public:
MyStruct::Builder m_ms;
MyClass() :
m_message ()
, m_ms (m_message.initRoot<MyStruct>()) // sometimes segfaults here but absolutely required
{
m_ms = m_message.initRoot<MyStruct>(); // sometimes helps
}
void deserializeFrom(std::string filename) {
int fd = 0;
::capnp::PackedFdMessageReader msg(fd);
auto reader = msg.getRoot<MyStruct>();
m_message.setRoot(reader); // This leads to future problems with m_ms
}
void modify() {
m_ms.setFoo("oh joy");
}
void serializeTo(std::string filename) {
int fd = 1;
writePackedMessageToFd(fd, m_message);
}
};
int main() {
MyClass c;
c.deserializeFrom("some.capnp");
std::cerr << "foo is " << c.m_ms.getFoo().cStr() << std::endl; // read things occasionally
c.modify();
c.serializeTo("next.capnp");
}