Problem with CDC:SetMapMode (in Release-Mode) [modified]
-
Hey, I've a MFC-Based DLL calling a special drawing function in another DLL (MFC extended). All works fine in debug-mode. But when I tried to test my DLL in release mode, the program crashes in the line with SetMapMode. Function in calling DLL (OnPaint):
... CPaintDC dc(this); //dc.SetMapMode(MM_LOMETRIC); <<<< Works fine here! PaintSpecialGraphics(&dc); ...
Function in DLL:int WINAPI PaintSpecialGraphics(CDC *pDC) { ... pDC->SetMapMode(MM_LOMETRIC); <<<< CRASH !!! ... }
Thanx for your help..... P.S: When I try to call the "PaintSpecialGrafics" from my Application (.exe) all works fine... -- modified at 18:09 Thursday 31st August, 2006First I'd make sure you're building the release build with debug info. Follow these steps in MSVC 6: - Select "Project->Settings...". - Select the "Release" configuration. - Select "C/C++" tab. - Select "General" in the "Category" combo. - In the "Debug info" combo select "Program Database". - Select the "Link" tab. - Select "Debug" in the "Category" in combo. - Tick "Debug info" and "Separate types" and choose "Microsoft format". - Select OK. - Rebuild all. If you're using a newer version of visual studio you'll have to adjust these steps. Now reproduce the error are see where the error occurs in the MFC source code; this might give you more chance of understanding what's going wrong.
Steve
-
Hey, I've a MFC-Based DLL calling a special drawing function in another DLL (MFC extended). All works fine in debug-mode. But when I tried to test my DLL in release mode, the program crashes in the line with SetMapMode. Function in calling DLL (OnPaint):
... CPaintDC dc(this); //dc.SetMapMode(MM_LOMETRIC); <<<< Works fine here! PaintSpecialGraphics(&dc); ...
Function in DLL:int WINAPI PaintSpecialGraphics(CDC *pDC) { ... pDC->SetMapMode(MM_LOMETRIC); <<<< CRASH !!! ... }
Thanx for your help..... P.S: When I try to call the "PaintSpecialGrafics" from my Application (.exe) all works fine... -- modified at 18:09 Thursday 31st August, 2006I suspect it's due to the passing of the DC object between two DLLs, but I can't be sure where exactly the problem is. To narrow it down, check the following: 1) Check the validity of pointer pDC in PaintSpecialGraphics(CDC *pDC); 2) Add thhis code to the calling DLL and see if it works locally: CDC* pDC = &dc; pDC->SetMapMode(MM_LOMETRIC); 3) To further test, you could change the function signature from PaintSpecialGraphics(CDC *pDC) to PaintSpecialGraphics(CPaintDC &dc). Etc.
Best, Jun
-
I suspect it's due to the passing of the DC object between two DLLs, but I can't be sure where exactly the problem is. To narrow it down, check the following: 1) Check the validity of pointer pDC in PaintSpecialGraphics(CDC *pDC); 2) Add thhis code to the calling DLL and see if it works locally: CDC* pDC = &dc; pDC->SetMapMode(MM_LOMETRIC); 3) To further test, you could change the function signature from PaintSpecialGraphics(CDC *pDC) to PaintSpecialGraphics(CPaintDC &dc). Etc.
Best, Jun
I suspected the same thing but, like you, can't pinpoint the exact problem. That's why I think knowing where things go wrong inside MFC might help. Perhaps it's possible that different compiler settings were used in the EXE and the DLL and this caused the layout of the
CDC
class differ. Or perhaps it's a mixed allocator problem: classCDC
in the EXE allocates some data on its heap the the DLL free it on a different heap. It would probably be a good idea to pass the rawHDC
when passing a DC between modules.Steve
-
Hey, I've a MFC-Based DLL calling a special drawing function in another DLL (MFC extended). All works fine in debug-mode. But when I tried to test my DLL in release mode, the program crashes in the line with SetMapMode. Function in calling DLL (OnPaint):
... CPaintDC dc(this); //dc.SetMapMode(MM_LOMETRIC); <<<< Works fine here! PaintSpecialGraphics(&dc); ...
Function in DLL:int WINAPI PaintSpecialGraphics(CDC *pDC) { ... pDC->SetMapMode(MM_LOMETRIC); <<<< CRASH !!! ... }
Thanx for your help..... P.S: When I try to call the "PaintSpecialGrafics" from my Application (.exe) all works fine... -- modified at 18:09 Thursday 31st August, 2006I suggest you side step the problem as follows: 1. Change the signature of the DLL function as follows:
int WINAPI PaintSpecialGraphics(HDC hDC);
2. Adjust the implementaion in the DLL so it looks like this:int WINAPI PaintSpecialGraphics(HDC hDC) { CDC dc; dc.Attach(hDC); // Do stuff with 'dc' here... dc.Detach(); }
3. Make the call like this:CPaintDC dc(this); PaintSpecialGraphics(dc);
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons: - MFC's handle map implementation. - Different heaps. - Different compiler settings in EXE and DLL.Steve
-
I suspect it's due to the passing of the DC object between two DLLs, but I can't be sure where exactly the problem is. To narrow it down, check the following: 1) Check the validity of pointer pDC in PaintSpecialGraphics(CDC *pDC); 2) Add thhis code to the calling DLL and see if it works locally: CDC* pDC = &dc; pDC->SetMapMode(MM_LOMETRIC); 3) To further test, you could change the function signature from PaintSpecialGraphics(CDC *pDC) to PaintSpecialGraphics(CPaintDC &dc). Etc.
Best, Jun
-
I suspected the same thing but, like you, can't pinpoint the exact problem. That's why I think knowing where things go wrong inside MFC might help. Perhaps it's possible that different compiler settings were used in the EXE and the DLL and this caused the layout of the
CDC
class differ. Or perhaps it's a mixed allocator problem: classCDC
in the EXE allocates some data on its heap the the DLL free it on a different heap. It would probably be a good idea to pass the rawHDC
when passing a DC between modules.Steve
-
Perhaps you can quote the file/line (and MFC version) and paste in some code surrounding the fault.
Steve
-
I suggest you side step the problem as follows: 1. Change the signature of the DLL function as follows:
int WINAPI PaintSpecialGraphics(HDC hDC);
2. Adjust the implementaion in the DLL so it looks like this:int WINAPI PaintSpecialGraphics(HDC hDC) { CDC dc; dc.Attach(hDC); // Do stuff with 'dc' here... dc.Detach(); }
3. Make the call like this:CPaintDC dc(this); PaintSpecialGraphics(dc);
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons: - MFC's handle map implementation. - Different heaps. - Different compiler settings in EXE and DLL.Steve
Stephen Hewitt wrote:
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons: - MFC's handle map implementation. - Different heaps. - Different compiler settings in EXE and DLL.
Does this mean, that there is no way to exchange data (pointer to mfc objects) between mfc dlls? My concept is to exchange cobject dervied classes (pointer) between my application and a mfc-based calculation dll..
-
Perhaps you can quote the file/line (and MFC version) and paste in some code surrounding the fault.
Steve
Ok, here is the function where the debugger stops (wingdi.cpp, MFC 7.1, VS2003 SP1):
CPoint CDC::SetViewportOrg(int x, int y) { ASSERT(m_hDC != NULL); CPoint point; if (m_hDC != m_hAttribDC) VERIFY(::SetViewportOrgEx(m_hDC, x, y, &point)); if (m_hAttribDC != NULL) VERIFY(::SetViewportOrgEx(m_hAttribDC, x, y, &point)); return point; <<<<<<<<<<<<<<< I can't imagine why the debugger/program stops at this line...?
-
Stephen Hewitt wrote:
I suspect you can't use MFC classes across DLL boundries. Here are some possible reasons: - MFC's handle map implementation. - Different heaps. - Different compiler settings in EXE and DLL.
Does this mean, that there is no way to exchange data (pointer to mfc objects) between mfc dlls? My concept is to exchange cobject dervied classes (pointer) between my application and a mfc-based calculation dll..
It depends on how the classes are implemented and packaged. Consider this example:
class CExample { public: int GetNum() { return g_Number; } }
In this class theCExample::GetNum
method access a global variable. If you include this class into an EXE and a DLL then the version in the EXE will access a global in the EXE; but when called from the DLL it will access a global (of the same name) in the DLL. Problems will probably ensue. There are ways around this issue but perhaps the MFC classes are simply not designed to be passed between module boundries (like this class). Unless you know it is same to do this the only safe assumption is that you can't.Steve