序列化指针指向的内存






2.78/5 (3投票s)
本文演示了对动态分配的内存进行序列化,该内存既不是 CObject 的派生类,也不是 CString。 也就是说,即使对象不是 CObject 派生类对象,也可以在 MFC 中实现变量或对象的持久化。
引言
有时我们需要保存指针变量指向的内存,而不是指针变量本身,即堆上分配的内存。 例如,当我们创建一个(不是从 CObject
派生的)堆对象并希望序列化该对象时,**或者**我们使用 C / C++ 内存分配例程(malloc
、calloc
或 new
)或 Windows API 函数(GlobalAlloc
、HeapAlloc
、VirtualAlloc
等)分配一些内存。
MFC 序列化架构没有提供任何显式机制来保存由非 CObject
派生类的对象指针变量指向的内存。 如果指针是 CObject
或 CString
派生类的对象,则可以对其进行序列化。 但是,如果它是 char *
,可以对其进行序列化吗? 很可能不行。 这就是我撰写本文的原因,以解决这个问题。 本文旨在为非 CObject
派生类添加序列化,即即使对于非 CObject
派生类对象,也能在 MFC 中实现对象持久化。
背景
其基本思想是,首先需要使用以下函数保存内存大小
void CArchive::WriteCount(DWORD_PTR dwCount);
现在,让我们使用以下函数保存指针变量指向的内存
void CArchive::Write(const void* lpBuf, UINT nMax);
现在,在恢复的情况下,首先需要使用以下函数读取指针变量指向的内存大小
DWORD_PTR CArchive::ReadCount();
然后您需要使用以下函数读取内存内容
UINT CArchive::Read(void* lpBuf, UINT nMax);
使用代码
使用上述基本思想,您可以创建以下两个实用函数
void WritePointer(CArchive& ar, const void* lpBuf, UINT nMax);
void ReadPointer(CArchive& ar, void*& lpBuf, UINT& nMax);
上述函数的实现如下
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);
}
}
现在让我们使用上述函数
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);
}
}
历史
- 2007 年 11 月 8 日 - 创建文章。