The simplest thing is to write and read structs on disk. First, define what you want to store:
struct SavedState {
int32_t a;
float b;
char c[100]; // n.b. you cannot use std::string here!
} __attribute__((__packed__));
static_assert(std::is_trivially_copyable<SavedState>::value,
"SavedState must be trivially copyable");
Then, create some state and save it:
SavedState s = { 1, 2.3 };
snprintf(s.c, sizeof(s.c), "hello world!");
std::ofstream outfile("saved.state", std::ios::binary);
outfile.write(reinterpret_cast<char*>(&s), sizeof(s));
if (!outfile)
std::runtime_error("failed to write");
Then, restore it:
SavedState t;
std::ifstream infile("saved.state", std::ios::binary);
infile.read(reinterpret_cast<char*>(&t), sizeof(t));
if (!infile)
throw std::runtime_error("failed to read");
Some important notes:
std::ios::binary
is needed to prevent streams from "normalizing" newlines (you're storing binary data, not text).
__packed__
is needed to make sure the structure has the same size on all systems. Ditto int32_t
instead of just int
.
- This code doesn't handle "endian" issues, meaning you need to save and restore the state on the same "endianness" of machine, so you cannot for example save on x86 and load on SPARC.
- The struct must not contain any pointers, meaning it cannot contain most STL containers, strings, or any other dynamically-sized elements. In C++11 you can ensure this at compile time using the
static_assert
; in earlier versions of C++ you can use BOOST_STATIC_ASSERT
if you want.