Streaming .COM objects

Started by
2 comments, last by Dyronix 9 years, 8 months ago

Hi there,

I'm busy with handeling content ( textures, meshes, etc).
I'd like to stream data to a binary file and then when I need them I just read everything from the binary file.
The problem is: I can stream everything from custom made classes to basic variables like integers etc, but when I try t read a COM object it just won't work.

this is what my writer looks like:


ContentTypeWriter& ContentTypeWriter::operator<<(ID3D11ShaderResourceView** resource)
{
Write(&resource, sizeof(ID3D11ShaderResourceView));
return *this;
}

void ContentTypeWriter::Write(const void* buffer, size_t length)
{
m_Stream->write((char*)buffer, length);
 
if (!*m_Stream)
Logger::Log(_T("File::write Error"), LOGTYPE_ERROR, false);
}

this is what my reader looks like:


ContentTypeReader& ContentTypeReader::operator>>(ID3D11ShaderResourceView** resource)
{
	Read(&resource, sizeof(ID3D11ShaderResourceView));
	return *this;
}
void ContentTypeReader::Read(void* buffer, size_t length)
{
	m_Stream->read((char*)buffer, length);

	if (!*m_Stream)
		Logger::Log(_T("File::write Error"), LOGTYPE_ERROR, false);
}

Everytime I load my ShaderResourceView it comes out as a 0x000000, but all my other variables are parsed the same way and they come out just like I saved them.

Does anybody have any idea what I'm doing wrong?

Advertisement
Short answer: If you ever save/load a memory address, you're doing it wrong (with some extremely rare exceptions that I won't go into detail about because they won't help you).

Long answer: Instead of saving a pointer, save information that lets you recreate the desired data structure or find the existing data structure if you expect it to already be somewhere in RAM. For example, you might give each type a unique ID followed by data which lets you call a particular constructor, factory method, search through an existing object list, etc. This process is called serialization/deserialization and can be easy or complicated, depending on how flexible your format needs to be - you should do some Google investigation about what serialization is to get some ideas on how you could apply it to your situation.

I'm not intimately familiar with DX11, so I'm just going off of what I googled just now. Here's what I would do:

Saving:
- Write information that lets you create or find the ID3D11Resource* that you will need for the first parameter to CreateShaderResourceView. I am not familiar with DX11 so you'll have to figure out how you want to do this on your own.
- Write the SRV's D3D11_SHADER_RESOURCE_VIEW_DESC contents to the stream. This struct appears to be a POD (plain old data - in other words, a single contiguous block of data with no pointers to anything else), so this should work. You can save this in the manner you're using above.

Loading:
- Load the information that lets you create or find the ID3D11Resource* you need.
- Load the D3D11_SHADER_RESOURCE_VIEW_DESC from the stream.
- Call ID3D11Device::CreateShaderResourceView using those two pieces of information. This will give you the interface pointer to the newly constructed resource.


Alternatively, if your code works by creating a bunch of ShaderResourceViews in memory and you aren't using the stream itself to construct them, you can simply save/load a unique ID which allows you to find the existing ShaderResourceView object which already exists in memory. Though you can't use a pointer, you may be able to use an array index, GUID, or string for this.
Much has been written about the topic. Use the search term: serialization

Thanks for the reply Nypyren, I'll take a look at it.

This topic is closed to new replies.

Advertisement