Re: Memory corruption of DLL class object
On Fri, 20 Feb 2009 14:44:01 -0800, BoHuang
<BoHuang@discussions.microsoft.com> wrote:
Thank you. That was the correct diagnostic. Now the release config works:
MyMFCApp.exe /MD
renderer.dll /MD
nvImage.dll /MD
But for Debug:
MyMFCApp.exe /MDd
renderer.dll /MDd
nvImaged.dll /MDd (notice the 'd' for debug, Nvidia's convention)
I encounter loss of internal data in nvImage.dll depending whether in
MyMFCApp.exe or renderer.dll it is accessed.
Some nvImage.dll functions:
void nv::Image::create(int w, int h)
{
this->stdVectorOfFloatPtrs.push_back( new float[w*h*4] );
this->width = w;
this->height = h;
}
float* nv::Image::getLevel( int i)
{
return this->stdVectorOfFloatPtrs[i];
}
In myMFCApp.exe:
//created on the heap in myMFCApp.exe
nv::Image* pImage = new nv::Image();
//create a buffer on the heap in nvImage.dll
pImage->create(256,256);
//Still in MyMFCApp.exe. Check data exists. Yes it does.
float* internalData = pImage->getLevel(0);
//Pass the pointer and program control to renderer.dll
myRenderer->modifyImage( pImage );
void renderer::modifyImage( nv::Image* pImage)
{
//If examine pImage->stdVectorOfFloatPtr here it has size 1
//As soon as I step into getLevel(), which is in nvImage.dll
//pImage's stdVectorOfFloatPtr has size 0 rather than 1
//width and height however are still 256
//Thus access violation is triggered here
float* internalData = pImage->getLevel(0);
//subsequent code to modify internalData
}
How is the data lost? Are there some different heap spaces issue for dlls?
In Windows, EXEs and DLLs are collectively known as "modules", and each
module either embeds a static CRT of some flavor or links to a CRT DLL of
some flavor. By "CRT", I mean C and C++ runtime libraries, which contain
data including heap, file descriptors, errno, etc. The only way for two
modules to share this CRT data is by linking to the exact same CRT DLL.
There may also be issues such as class size differences due to debugging
and other switches which are very relevant when sharing C++ objects across
module boundaries. C++ templates impose additional constraints, because
absent special techniques, they are instantiated in each module that uses
them, so each module gets its own set of code. (Much more problematic is
template static data.) The same sort of consideration applies to inline
functions. In order to tear down the module boundary and share C++ objects
between modules, each module has to agree on things such as the heap,
object size and layout, and so forth. With these things in mind, if you
look at the differences between the compilation and linkage environments
for the non-working case, you should be able to find some violation that
accounts for the behavior you observed.
--
Doug Harrison
Visual C++ MVP