CByteBuffer implementation passed between modules
Hello, we have created a CByteBuffer class. It stores an abitrary number of
bytes on the heap. Simplified:
class CByteBuffer
{
public:
CByteBuffer()
{
m_pBuf = NULL;
} ;
Set (LPVOID p, size_t size)
{
m_pBuf = new BYTE[size];
memcpy (m_pBuf, p, size);
};
~CByteBuffer()
{
if (m_pBuf) delete[] m_pBuf;
};
protected:
LPBYTE m_pBuf;
}
The issue is this class is compiled into both MyExe.exe and MyDLL.dll.
MyExe.exe depends on MyDLL.dll. MyExe creates an instance of CByteBuffer
and passes it to MyDLL to be filled. Then MyExe deletes CByteBuffer:
In MyExe:
void foo()
{
CByteBuffer buf;
FuncInMyDLL (buf);
}
In MyDLL:
void FuncInMyDLL (CByteBuffer &buf)
{
LPCTSTR p = "Hello Mom";
buf.Set (p);
}
The problem now is that the CByteBuffer::m_pBuf was allocated using the
"new" in MyDLL and deleted using the "delete" in MyEXE (when the instance
goes out of scope). If the RTL is statically linked into both MyApp and
MyDLL, then the "delete" causes a crash since the memory was allocated using
a different instance of the heap. If the RTL is dynamically linked, it's
fine since the same heap is shared. But I don't want the users of my
CByteBuffer class to be forced to dynamically link the RTL.
One fix is to add private "allocate" and "deallocate" member functions and
initialize it to point to "new" and "delete" in the ctor. This means they
are set to the heap functions of the module which instantiated the instance.
Then the private "allocate" and "deallocate" member functions are used to
create and destroy CByteBuffer::m_pBuf, ensuring that no matter which module
actually calls these, the heap functions of the same module (the module that
instantiated the instance) will be called:
class CByteBuffer
{
public:
CByteBuffer()
{
m_pBuf = NULL;
m_allocate = BYTE::new[]; // how to specify the new BYTE[]
operator?
m_deallocate = delete[]; // how to specify the delete[]
operator?
} ;
Set (LPVOID p, size_t size)
{
m_pBuf = m_allocate(size);
memcpy (m_pBuf, p, size);
};
~CByteBuffer()
{
if (m_pBuf) m_deallocate(m_pBuf);
};
protected:
LPBYTE m_pBuf;
LPBYTE (*m_allocate)(size_t size);
void (*m_deallocate)();
}
So, does this look like a reasonable way to workaround the problem? If so,
how to specify the "new" and "delete" functions to assign to the member
variables? And does CString have the same issue? I believe it does... does
CString do something similar to this, or is it just prohibited from passing
CString's to different modules that have statically linked MFC?
Thanks,
David