Skip to main content
gamedev.net
🔒 Locked

Saving Classes/Structs/Objects C/C++

Started by ViperG 7 replies 1.8k views
Original Post
ViperG
ViperG
Well I am getting to the part where I need File I/O.. Almost everything is structured as a struct or a class, and I need to save this data to files and read in later etc.

The two methods that only exist seem to be:

1) Serialization
2) Save each member one at a time.

Option 1 seems to be the most popular for example Boost::serialization, however i'm having linking problems trying to get the .lib file for serialization to work.

2) save each member in a text format, or possibly binary.

I was curious on what other people do and if there are any tricks or advanced topics to make this easier. I probably have about 10-20 objects I need to save to different files, and it looks like I am going to have to type alot of tedious code to be able to save my data as a text file.
Black Sky A Star Control 2/Elite like game
Rycross
Rycross
Saving each member in a text format is serialization, just fairly simple serialization. You've only really given one option here.

The other alternative is to just save the in-memory binary representation of your struct to a file. This is not recommended, as its brittle and likely to cause you great pain and anguish later.

And as an answer, I like boost::serialization. What kind of linking problems are you seeing?
ViperG
ViperG
Well I used bjam to build serialization and it produced

libboost_serialization-vc80-mt-gd-1_44.lib

however when I included the necessary headers for serialization it is looking for

libboost_serialization-vc80-mt-s-1_44.lib

I tried renaming the file but i still got compile errors. So I put that on pause
and decided maybe I should just save to a text file.

Of course on the boost homepage they have a installer package that has the built libraries, but when I tried to download it i got a file not found message from the website.

So that got me mad and I stopped going any further with boost serialization.
Black Sky A Star Control 2/Elite like game
Zipster
Zipster
We really need to have a bot that patrols the forums and posts this link every time serialization is mentioned [smile]

Quote:
[]Original post by ViperG
Well I used bjam to build serialization and it produced

libboost_serialization-vc80-mt-gd-1_44.lib

however when I included the necessary headers for serialization it is looking for

libboost_serialization-vc80-mt-s-1_44.lib

I tried renaming the file but i still got compile errors.

The filename gives you some hints as to when it should be used:

lib* = Static Library
mt = Multithreaded
gd = Debug
s = Static Runtime

Lack of any of those tags means the opposite of what it indicates. If your project configuration settings don't match (namely the runtime), you'll have problems. The boost headers are smart enough to know which library to look for, so if they're looking for "libboost_serialization-vc80-mt-s-1_44.lib" that's what you need to give them. It's possible you didn't provide enough options to bjam, which is why it's not generating the library you need. To err on the safe side, you can use this to build everything:

bjam toolset=msvc --build-type=complete stage

Substitute in your preferred toolset. It'll take up some HDD space, but you'll never be missing a library.
Zahlman
Zahlman
Quote:
Original post by ViperG
Well I am getting to the part where I need File I/O.. Almost everything is structured as a struct or a class, and I need to save this data to files and read in later etc.

The two methods that only exist seem to be:

1) Serialization


What? No, "serialization" is the term for the process of saving the data. No matter how you do it, it's serialization.

Quote:
2) Save each member one at a time.


That's the basic approach to dealing with members of a struct; sure. You need to know how to save each member, though.

Quote:
2) save each member in a text format, or possibly binary.


Uh, that's the same thing?

You don't have to use a library (although it may make things much easier) but you do have to know what you're doing. Your file has to contain data which makes it possible to reconstruct the struct later, when things aren't necessarily in the same places in memory. That means you have to account for pointed-at things (you can't just write the pointer), and keep track of the length of variable-length things.

Please, read this.

Quote:
Original post by Zipster
We really need to have a bot that patrols the forums and posts this link every time serialization is mentioned [smile]


Errrr, I thought I was that bot? [smile]
ViperG
ViperG
Alright thanks, I'll try boost again and see if I can get it working.

Would boost::serialization be able to serialize a vector of my own data type, like a struct?

My other question is what's the industry standard for this? Maybe this question is better suited in the game programing forum. Just curious because writing out all this data to multiple data files seems daunting and time consuming.
Black Sky A Star Control 2/Elite like game
Bearhugger
Bearhugger
I don't think there is any way around saving each member one after the other. You can write a whole struct in one shot with fwrite(f, &s, 1, sizeof(s)), but that only works if the struct contains no virtual function or pointer. And even then, if you do that, the compiler can still mess you up because of byte packing, which might cause incompatibility between two versions of a same program compiled by a different compiler.

I would take a wild guess and suppose that industry standard for serialization is XML serialization. Dragon Age saves tons of data in XML. Also, OpenOffice.org (not a game but still serializes) serielizes its documents in compressed XML.
KulSeran
KulSeran
Quote:
Original post by Bearhugger
You can write a whole struct in one shot with fwrite(f, &s, 1, sizeof(s)), but that only works if the struct contains no virtual function or pointer. And even then, if you do that, the compiler can still mess you up because of byte packing...

I agree. Writing out the struct like that is bad mojo. There are too many things that can go wrong.

Quote:
Origional post by ViperG
Would boost::serialization be able to serialize a vector of my own data type, like a struct?

Yes. Thats the point. You write your serializer for your struct, and you are done. boost has serializers for STL containers, and strings. You just have to write the little parts that tie all your stuff into the serializer. But you will still have to deal with pointers on your own, especially since there are several edges cases you may want/need to deal with.

Quote:
Origional post by ViperG
My other question is what's the industry standard for this?

Don't know.
Doom used lots of custom text files. Homeworld 2 used lots of Lua scripts. Many games use binary formats.

At work we use custom binary formats for all our data. Everything is designed to be loaded in place. So textures, models, and sounds are all in the exact format the hardware wants (no processing text files!). All our game data is directly castable as a POD struct, only requiring fixups for pointers. This results in very fast load times, and offline predictable memory footprints from resources.

The caveat here is that it takes a lot of work. Serialization has to take into account all the variables between the sources and destination.
*Each machine has a different format for everything. PSPs load different textures than Xbox360s for instance.
*There are different format for basic types (big/small endian), so packing binary data for the X360 is different from packing for PC.
*Each processor has different basic data sizes for efficiency (32 or 64 bit).
*Some machines require specific padding or alignment (ie. 128bit for VMX/SSE data)
*Sometimes disk sector sizes matter significantly for how you pack stuff.
*Not all machines have uniform memory layouts, and you have to pack some data separate from other data so it loads into the correct memory locations.

Also note that binary formats are impossible to work with once they are packed. It can be important to have either text and binary formats (very easy using something like boost::serialization), or automated text->binary packing tools. That way it is far easier to edit and view errors in your data.
Washu
Washu
To further expand on this:

There is no standard format for people to store stuff in. Each has advantages and disadvantages. It is up to you to balance the formats you wish to support and decide on what mechanism you will use. You may even support many different mechanisms for debug and release, overriding and other techniques.

As an example: When dealing with console platforms it is more important to have your data be read in order than necessarily the size of the data1. As such your data may grow through resource duplication between discrete loads just to increase load performance by linearizing the storage on the actual storage medium.

1 This poses a problem on platforms like the xbox which is still DVD based, as many games are easily exceeding the size of the storage disk (hence why Mass Effect 2 was 2 DVDs). Platforms that support newer media formats (such as blu-ray) don't necessarily have this issue... YET.
In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.