Boost Archive intialization as a class member

I am currently serializing data in a class in which a member function is called and passed the data and I declare a static boost::archive in that function and serialize the data to a binary file.  This works fine when I deserialize (in a while loop with EOF condition) but now I would like to serialize to the same file/archive from other functions in the class.  The Boost tutorials do not show any other way to intialize an archive.  

Basically I want to declare a boost::archive::binary_oarchive as a member variable.  Problem is, how do I initialize it, say, in the constructor after I have opened a file stream?  My instinct tells me this is not allowed, but I was hoping there was a way to do this.

 (FYI, I've tried to serialize by declaring different instances of the archive file in each function with a common file stream, but on deserialization, i get an "invalid signature" exception).
shootahAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

evilrixSenior Software Engineer (Avast)Commented:
Why not create the archive on the heap and have a class member pointer to it? That way you can create it once your prerequisite file is open and you're ready to set up the archive.
0
shootahAuthor Commented:
I have tried this in the past.  This is a bit embarassing because this question is probably trivial, but how do I use the insertion operator for an archive pointer (I guess for any pointer that overloads the insertion operator)? "ar<<data" doesn't compile:

"no match for ‘operator<<’ in ‘((CDmsoHlaFederateAmbassador*)this)->CDmsoHlaFederateAmbassador::m_ar << data’"

If I'm not getting what you are asking me to do, maybe you can post an example?  Here is what I've implemented more or less.





 
typedef boost::archive::binary_oarchive oarchive_t;

class SomeClass{

public:
std::ofstream m_ofStream;   
oarchive_t* m_ar;

SomeClass(std::string sRecordFileName){

m_ofStream.open(sRecordFileName.c_str(), std::ios::binary);
oarchive_t* oa = new oarchive_t(m_ofStream);
m_ar = oa;
}

Foo(SerializeableClass data){
  
  m_ar<<data;

}

}

Open in new window

0
jkrCommented:
>>"ar<<data" doesn't compile

Well, that should simply be '(*m_ar)<<data;' - since you are using a pointer, you need to dereference it.
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

jkrCommented:
BTW, back to your original intention - why not using that like
typedef boost::archive::binary_oarchive oarchive_t;

class SomeClass{

public:
std::ofstream m_ofStream;   
oarchive_t m_ar;

SomeClass(std::string sRecordFileName) : m_ar(m_ofStream){ // set stream object for construction

m_ofStream.open(sRecordFileName.c_str(), std::ios::binary); // Now, actually open it

}

Foo(SerializeableClass data){
  
  m_ar<<data;

}

}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
shootahAuthor Commented:
I love experts exchange.  It magnifies my inept programming knowledge every time.  :)

jkr,
  I implemented evilrix's suggestion with your help and it works.  I tried your second implementation as well but there seems to be an exception thrown.  I'm not sure what the exception is because it falls into the catch all.  It does not get caught by (boost::archive::archive_exception) so maybe it's a stream exception or something.  Creating the archive off the stack is preferable (seems cleaner I guess).  Is there a way to discover the exception thrown?  Maybe via gdb?
0
jkrCommented:
When stepping through the code, gdb should indeed report which exception that was. BTW, does the following work?
SomeClass(std::string sRecordFileName) : m_ofStream(sRecordFileName.c_str(), std::ios::binary), m_ar(m_ofStream){ 

}

Open in new window

0
evilrixSenior Software Engineer (Avast)Commented:
>> It does not get caught by (boost::archive::archive_exception)
All boost exceptions derive from std::exception so just catch that by reference and use the what() member to display the reason.

http://www.cplusplus.com/reference/std/exception/exception/

catch(std::exception const & e)
{
    std::cerr << e.what();
}

Open in new window

0
shootahAuthor Commented:
Yep that worked.  Thanks.
0
shootahAuthor Commented:
Last comment was in reference to jkr's suggestion btw.
0
shootahAuthor Commented:
evilrix, thanks, i'll keep that in mind in the future.
0
evilrixSenior Software Engineer (Avast)Commented:
BTW: AFAIK you can't create an archive object with a stream what is not open (at least, not with my somewhat limited experience of this part of the boost library).
0
shootahAuthor Commented:
Yeah, that's what it looks like.  Once the stream was initialized per jkr's suggestion it seemed to work.
0
jkrCommented:
I was guessing that the binary_oarchive might check the stream state, thus the 2nd suggestion - yet I have to admit it was just a shot in the dark ;o)
0
evilrixSenior Software Engineer (Avast)Commented:
Hahaha... I've been working with archive just recently so I should have realised earlier what the problem was. It only dawned on me after I posted the comment about how to catch the exception. Heh -- it's been a long day at the office :)
0
jkrCommented:
>>it's been a long day at the office :)

Still there and trying to ignore the urge to punch the developers of MS' 'MIDL' in the stomach ;o)
0
evilrixSenior Software Engineer (Avast)Commented:
>>  trying to ignore the urge to punch the developers of MS' 'MIDL'
Don't fight it... seriously -- they deserve it :)
0
jkrCommented:
Indeed - especially when a line like

int BeapInit([in, string] const char* pszInit);

results in generated code that reads

/* interface Beap */
/* [auto_handle][version][uuid] */

int BeapInit(
    /* [string][in] */ const unsigned char *pszInit);

and you are looking for the reason of the 'unresolved external' errors for over an hour pulling your hair out  :-(
0
evilrixSenior Software Engineer (Avast)Commented:
That'll teach you to use COM :)

So glad I am not a Windows programmer!!!
0
jkrCommented:
COM? Que? RPC! ;o)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.