Solved

CArchive::GetObjectSchema always returns -1

Posted on 1998-08-24
11
577 Views
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?
0
Comment
Question by:barrett
[X]
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
11 Comments
 
LVL 8

Expert Comment

by:Answers2000
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.

0
 

Author Comment

by:barrett
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?
0
 

Author Comment

by:barrett
ID: 1321225
I just tried putting the GetObjectSchema call in the first doc class that touches the archive, and I get the same results...
0
Industry Leaders: 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!

 
LVL 8

Expert Comment

by:Answers2000
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 ?
0
 

Author Comment

by:barrett
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.

0
 

Author Comment

by:barrett
ID: 1321228
Er, I meant to say that CChartView derives from OPView...
0
 
LVL 2

Expert Comment

by:warmcat
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.
0
 
LVL 8

Expert Comment

by:Answers2000
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
0
 

Accepted Solution

by:
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)
{
  ar.SerializeClass(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.

0
 

Author Comment

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

Expert Comment

by:dmunoz
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.

0

Featured Post

Technology Partners: 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!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
iSeries FTP Exit Program 8 173
wordappend challenge 8 249
Sed question 2 139
Making an alias 7 121
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
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.
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

751 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