Click here to Skip to main content
15,884,237 members
Articles / Desktop Programming / MFC

Serialization of Memory Pointed by a Pointer

Rate me:
Please Sign up or sign in to vote.
2.78/5 (3 votes)
8 Nov 2007CPOL1 min read 33.2K   448   9   2
This article is a demonstration of serialization of dynamically allocated memory which is neither a derived class of CObject nor a CString. I.e., a kind of Variable or Object Persistence in MFC even if the object is a non-CObject derived class object.

Introduction

Some times we need to save memory pointed by the pointer variable rather than the pointer variable itself, i.e., memory allocated on heap. For example, when we create an object (which is not derived from CObject) on the heap and we want to serialize the object, or we allocate some memory either using C / C++ memory allocation routines (malloc, calloc, or new) or Windows API functions (GlobalAlloc, HeapAlloc, VirtualAlloc etc.).

The MFC serialization architecture doesn't provide any explicit mechanism to save memory pointed by a pointer variable of an object of a class which is not derived from CObject. If the pointer is an object of a class which is derived from CObject or CString, it can be serialized. But if it is a char *, can it be serialized? Most probably, it can't be. That is why I present this article to solve the problem. This article is for adding serialization to non-CObject derived classes, i.e., Object Persistence in MFC even for non-CObject derived class objects.

Background

The basic ideas behind this is that you will first need to save the size of memory by using the following function:

C++
void CArchive::WriteCount(DWORD_PTR dwCount);

Now, let's save the memory pointed by the pointer variable by using the following function:

C++
void CArchive::Write(const void* lpBuf, UINT nMax);

Now, in the case of restoring back, you will first need to read the size of memory pointed by the pointer variable by using the following function:

C++
DWORD_PTR CArchive::ReadCount();

Then you will need to read the memory content by using the following function:

C++
UINT CArchive::Read(void* lpBuf, UINT nMax);

Using the code

Using the above basic ideas, you can make the following two utility functions:

C++
void WritePointer(CArchive& ar, const void* lpBuf, UINT nMax);
void ReadPointer(CArchive& ar, void*& lpBuf, UINT& nMax);

Implementation of the above functions is given below:

C++
void WritePointer(CArchive& ar, const void* lpBuf, UINT nMax)
{
    ar.WriteCount(nMax);
    ar.Write(lpBuf, nMax);
}

void ReadPointer(CArchive& ar, void*& lpBuf, UINT& nMax)
{
    ASSERT(lpBuf == NULL);

    nMax = UINT(ar.ReadCount());
    lpBuf = malloc(nMax);
    UINT nBytesRead = ar.Read(lpBuf, nMax);
    if (nBytesRead != nMax)
    {
        AfxThrowArchiveException(CArchiveException::endOfFile);
    }
}

Let's now use the above functions:

C++
CPointerSerializationDoc::CPointerSerializationDoc(): m_buf(NULL)
{
    wchar_t String[] = _T("This is the initialized value in m_buf.");
    UINT nMax = sizeof(String);
    m_buf = malloc(nMax);
    memcpy_s(m_buf, nMax, String, nMax);
}

void CPointerSerializationDoc::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
        // Let's store the actual content pointed by m_buf pointer;
        
        // Following is wrong, because this will store the pointer value, 
        // but not the actual content pointed by the pointer.
        // ar<<m_buf;

        // So use the following function;
        WritePointer(ar, m_buf, nMaxCount);
        //nMaxCount - size of memory content;
    }
    else
    {
        // Let's load the actual content pointed by m_buf pointer;

        // Following is wrong, because pointer value will be loaded but not 
        // the actual content pointed by the pointer.
        // ar>>m_buf;

        // So use the following function;
        UINT nMaxCount = 0;
        ReadPointer(ar, m_buf, nMaxCount);
    }
}

History

  • Nov. 8, 2007 - Article created.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Canon India Pvt Ltd
India India
Born and living in India, I'm an engineer in Computer Science & Engineering working in Canon India Pvt Ltd as a Module Leader responsible for coding, Team handling etc. I’m interested in leading a Project and working with C++, MFC, STL, COM and ATL.

Comments and Discussions

 
GeneralAfxReadStringLength/AfxWriteStringLength Pin
defrager10-Nov-07 7:02
defrager10-Nov-07 7:02 
Hi,

Use ar.ReadCount and ar.WriteCount to save length of buffer.
AfxReadStringLength/AfxWriteStringLength are designed to serialize length of strings and not supported by vc6.
AnswerRe: AfxReadStringLength/AfxWriteStringLength Pin
shriram_gupta10-Nov-07 16:05
shriram_gupta10-Nov-07 16:05 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.