CArchive::GetObjectSchema always returns -1

Posted on 1998-08-24
Last Modified: 2013-11-19
I'm trying to implement a serializable class with versioning, and I think I'm doing all the steps I'm supposed to: my class is declared with DECLARE_SERIAL, and it's defined with IMPLEMENT_SERIAL, and the third arg to the IMPLEMENT_SERIAL macro is (VERSIONABLE_SCHEMA | 4), just as DevStudio help tells me. Yet in my Serialize method, when I call ar.GetObjectSchema(), it always returns -1.

What gives?
Question by:barrett
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
  • +1

Expert Comment

ID: 1321223
(begin quote)

Calling this function is only valid when the CArchive object is being loaded (CArchive::IsLoading returns nonzero). It should be the first call in the Serialize function and called only once. A return value of (UINT)–1 indicates that the version number is unknown

(end quote)

Presumably your code looks something like (it should) :-

void CMyObject::Serialize(CArchive& ar)
  // <--- Point 2

  if (ar.IsLoading())    
    // <--- Point 1

    int nVersion = ar.GetObjectSchema();
    // get all the data goes here
  } else
    // save all the data goes here

Do you have code at Point 1 or point 2 that touches the object or the archive, if yes, this is why.


Author Comment

ID: 1321224
My code does look like your sample, and I don't have any code at Point 1 or Point 2. I am, however, using MsDev 4.1 (required for this project) and am worried that there might be a bug -- er, I mean, "issue" with that version.

This is happening is a derived (leaf) class, and the GetObjectSchema() call is happening after two doc classes (base and derived) and a view class (base for my class) have already read some stuff from the archive. Could this be my problem? Do I need to call GetObjectSchema from the very first class to touch the archive?

Author Comment

ID: 1321225
I just tried putting the GetObjectSchema call in the first doc class that touches the archive, and I get the same results...
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 1321226
It shouldn't have to a be a base class (leaf's should be okay".  However I'm suspicious of "and a view class".  

I think you should only be reading from the Doc class tree and not from the view as well.  Who is calling the view class serialization function ?

Author Comment

ID: 1321227
Here's the call stack up to the class I'm trying to serialize:

OPView::Serialize(CArchive & {...}) line 1186
CChartView::Serialize(CArchive & {...}) line 665
OPOleServerDoc::Serialize(CArchive & {...}) line 208
CChartDoc::Serialize(CArchive & {...}) line 292
COleDocument::LoadFromStorage() line 751

CChartDoc derives from OPOleServerDoc, and OPView derives from CChartView (I didn't write this). None of the other three classes are defined IMPLEMENT_SERIAL with the VERSIONABLE_SCHEMA flag, so I'm wondering if maybe each class must be defined this way. Some of these aren't even defined with the IMPLEMENT_SERIAL macro.


Author Comment

ID: 1321228
Er, I meant to say that CChartView derives from OPView...

Expert Comment

ID: 1321229
I recall reading somewhere many moons ago that the 'schema' thing was deprecated by Microsoft before anyone actually used it and is only there now for source compatability.  In my Serialize() members, I stick my own explicit version number in as the first item stored and ignore the Schema thing.

Expert Comment

ID: 1321230
Where did you read that warmcat ?  My (Microsoft Press) book doesn't say that and infact devotes quite a lot of space to it.

BTW your workround should work if implemented properly, I don't know what happens to existing files that user schema's though

Accepted Solution

dmunoz earned 100 total points
ID: 1321231
I use sucessfully SCHEMA serialization in my documents, but I rewrite a lot af thinks... for the problem your asking, I think this could be the solution:

after calling your base class serialization, add :

UINT schema=SerializeSchema (ar, RUNTIME_CLASS (CYourClass));

UINT schema is the variable that receive the schema while loading resource. It's the schema specific to your class.
you can test it in the "if (ar.IsLoading())" part of your serialization function.

to declare SerializeSchema function, do something like:

UINT CYourClass::SerializeSchema (CArchive &ar, CRuntimeClass *pClass)
  UINT schema=(ar.IsLoading ()) ? ar.GetObjectSchema () : (UINT) -1;
  return schema;

the trick is that the class need to be serialized, to enable the GetObjectSchema() function.
I write all of this a very long time ago, I hope I'm not saying something stupid. If my memory is fine, I think it should work.

Hope that help.


Author Comment

ID: 1321232
You rock, dmunoz -- this code works perfectly!

Expert Comment

ID: 1321233
Thank you :-))  I'm glad to help.
Something that could help you if you go longer in Serialization.
Schema number should be a 16b short, not a 32b int like it's describe in runtime library! So, be carefull not to use the 16 upper bits of your schema... this one took me hours to find... You can see why in ARCCORE.CPP, line 309. WORD (short) is the MFC way...

Have a nice development day.


Featured Post

Percona Live Europe 2017 | Sep 25 - 27, 2017

The Percona Live Open Source Database Conference Europe 2017 is the premier event for the diverse and active European open source database community, as well as businesses that develop and use open source database software.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
In this post we will learn different types of Android Layout and some basics of an Android App.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

623 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question