Solved

CArchive::GetObjectSchema always returns -1

Posted on 1998-08-24
11
545 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
  • 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
 
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Have you tried to learn about Unicode, UTF-8, and multibyte text encoding and all the articles are just too "academic" or too technical? This article aims to make the whole topic easy for just about anyone to understand.
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.
Video by: Mark
This lesson goes over how to construct ordered and unordered lists and how to create hyperlinks.

896 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now