Solved

"Use MFC in static/shared" crashes for static

Posted on 1998-08-04
12
841 Views
Last Modified: 2013-11-19
Hi !

I have a VC++ 5.0 mainframe application, whose only job is to  launch somes DLLs:
it consists of a dialog box with only a menu, when selecting a menu item, it calls a DllInit() from one of the associated DLLs.
Those DLLs, created with VC++5.0, are dialog boxes with buttons, to do some testing, for example FTP operations.
They are compiled with "Use MFC in a static library" option.

If the mainframe is compiled with Mfc dynamically linked, everything's perfect:
when selecting "Debug FTP" on main menu, the dialog box with ftp operations shows up.

If the mainframe is compiled with Mfc statically linked,
when selecting "Debug FTP" on main menu, the application crashes. The crash point is into afxwin1.inl:

_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle()
      { ASSERT(afxCurrentResourceHandle != NULL);
            return afxCurrentResourceHandle; }

When tracing into the DLL, the error occurs at OnInitDialog() into DLL Dlg class:
          m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

if removing that line, the same error occurs at       
      CDialog::Create(CFtpDebugDlg::IDD, this);


The Dlls are created like this:
init and export function:


CFtpDebugDlg* mp_FtpDebugDialog;

static AFX_EXTENSION_MODULE FtpDebugDLL = { NULL, NULL };

extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
      if (dwReason == DLL_PROCESS_ATTACH)
      {
            TRACE0("FtpDebug.DLL Initializing!\n");
            
            // Extension DLL one-time initialization
            AfxInitExtensionModule(FtpDebugDLL, hInstance);

            // Insert this DLL into the resource chain
            new CDynLinkLibrary(FtpDebugDLL);
      }
      else if (dwReason == DLL_PROCESS_DETACH)
      {
            TRACE0("FtpDebug.DLL Terminating!\n");
      }
      return 1;   // ok
}


extern "C" DLLEXPORT BOOL InitFtpDebug(void)
{
      HWND ForegndWnd =GetForegroundWindow();

      mp_FtpDebugDialog = NULL;
      mp_FtpDebugDialog = new CFtpDebugDlg();
      // call FtpDebug debug window creation
      mp_FtpDebugDialog->Create(ForegndWnd);
      mp_FtpDebugDialog->ShowWindow(SW_SHOWNORMAL);

      return TRUE;
}




///////////////////////////////////////////////////////////////
Dlg Class/////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

CFtpDebugDlg::CFtpDebugDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CFtpDebugDlg::IDD, pParent)
{
      //{{AFX_DATA_INIT(CFtpDebugDlg)
            // NOTE: the ClassWizard will add member initialization here
      //}}AFX_DATA_INIT
      // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
      m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

      //Added for DLL
      ASSERT(m_pFtpDebugParent != NULL);
      m_pFtpDebugParent = pParent;
      m_nFtpDebugID = CFtpDebugDlg::IDD;
}

//////////////////////////////////////////////
// Create:                                                      //
//            this function creates  window,      //
//            affects its identifier and parent,      //
//            initialises its top left corner's      //
//            position.                                          //
//////////////////////////////////////////////
void CFtpDebugDlg::Create(HWND hDcrWnd)
{
      CWnd pWndInsertAfter;

      // create / open debug window
      CDialog::Create(m_nFtpDebugID, this);
      pWndInsertAfter.FromHandle(hDcrWnd );
      SetWindowPos(  &pWndInsertAfter,  0,  0,  0,  0,  SWP_NOSIZE );

}

Thanks for you ideas,

Mike.
0
Comment
Question by:eskimo100997
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
12 Comments
 

Author Comment

by:eskimo100997
ID: 1320212
Edited text of question
0
 

Author Comment

by:eskimo100997
ID: 1320213
An Ice cream is offered to the first who finds the solution !
0
 

Expert Comment

by:TangCheng
ID: 1320214
 I already happed this question.I think this is a MFC's Bug.

  I already found the reason. Because if you use to dynamically linked to run your program, the DLL's Instance is same as application's Instance(App's hInstance is :0x40000, DLL's hInstance is:0x40000 too).So if DLL want to load Resource, it will search resource in application's resource address.So the application often crashes.

  If you use to static linked to run your program, the DLL's Initial Address is realy DLL's Address(0x100000).So you can run it good.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:eskimo100997
ID: 1320215
the DLL's Initial Address is realy DLL's Address(0x100000), and everything is staticaly linked, main and DLLs.
It does perfectly run when dynamicaly linked.
0
 

Author Comment

by:eskimo100997
ID: 1320216
Adjusted points to 300
0
 
LVL 8

Expert Comment

by:Answers2000
ID: 1320217
Your mistake is that the DLLs should be built to be MFC Extension DLLs (using shared MFCs) otherwise you have multiple independant copies of MFC in the same program fighting over common names & resources.

To change existing code, I'd recommend creating new empty DLLs with the class wizard, and then adding the existing source into the new DLLs (Add File To Project).  This won't take long and should be pretty easy.

Also I'd suggest you make the main app use MFC in shared library.  You can change this easily from the project settings.
0
 

Author Comment

by:eskimo100997
ID: 1320218
The aim of that project is to be run onto some PCs with no MFC nor VC++ installed.
It can't be compiled with dynamic links to MFCs.
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1320219
What does "Crashes" mean?  Do you mean you get an assertion failure?  At what line of which file?  In which version of MFC? Are you saying the assertion in AfxGetResourceHandle() is failing?  If so, can you provide a symbolic stack trace?

Or do you get an unhandled exception?  If so, what's the symbolic stack trace look like?

On which operating system are you running?

It's really important to ask complete questions if you want help.

B ekiM
0
 

Author Comment

by:eskimo100997
ID: 1320220
Sorry for the lack of information. I thought it was a common failure.
I'm working with VC++ 5.0, under win95

The error is "debug assertion failed" in Afxwin.inl line 22:
ASSERT(afxCurrentResourceHandle != NULL)

Call stack trace:

AfxGetResourceHandle() line 22
AfxFindResourceHandle(char * 0x000003a0, char * 0x0000000e) line 216 + 5 bytes
CWinApp::LoadIconA(unsigned int 0x000003a0) line 1022 + 26 bytes
CFtpDebugDlg::CFtpDebugDlg(CWnd * 0x00000000 {CWnd hWnd=0xc8000000}) line 28 + 17 bytes
InitFtpDebug() line 50 + 33 bytes
CWcp_ic_MainDlg::OnMenuFtp() line 168
DispatchCmdMsg(CCmdTarget * 0x0078fd04 {CWcp_ic_MainDlg hWnd=0x00000a84}, unsigned int 0x0000800d, int 0x00000000, void (void)* 0x00401028, void * 0x00000000, unsigned int 0x0000000c, AFX_CMDHANDLERINFO * 0x00000000) line 88
CCmdTarget::OnCmdMsg(unsigned int 0x0000800d, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 301 + 39 bytes
CDialog::OnCmdMsg(unsigned int 0x0000800d, int 0x00000000, void * 0x00000000, AFX_CMDHANDLERINFO * 0x00000000) line 96 + 24 bytes
CWnd::OnCommand(unsigned int 0x0000800d, long 0x00000000) line 2058
CWnd::OnWndMsg(unsigned int 0x00000111, unsigned int 0x0000800d, long 0x00000000, long * 0x0078fa70) line 1567 + 28 bytes
CWnd::WindowProc(unsigned int 0x00000111, unsigned int 0x0000800d, long 0x00000000) line 1555 + 30 bytes
AfxCallWndProc(CWnd * 0x0078fd04 {CWcp_ic_MainDlg hWnd=0x00000a84}, HWND__ * 0x00000a84, unsigned int 0x00000111, unsigned int 0x0000800d, long 0x00000000) line 217 + 26 bytes
AfxWndProc(HWND__ * 0x00000a84, unsigned int 0x00000111, unsigned int 0x0000800d, long 0x00000000) line 371
KERNEL32! bff73663()
KERNEL32! bff928e0()


Hope this will help.
0
 
LVL 1

Accepted Solution

by:
sudhirbrat earned 600 total points
ID: 1320221
When you are loading a resource from a DLL, you should change the resource handle of your application to the DLL resource handle.

Try following line of code when ever your calling resource related functions like LoadIcon, etc...

AFX_MANAGE_STATE(AfxGetStaticModuleState());

Try this and let me know the result.
0
 

Author Comment

by:eskimo100997
ID: 1320222
Great !
0
 
LVL 1

Expert Comment

by:sudhirbrat
ID: 1320223
Where is my ICE CREAM !!!!!
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Adapt this command to show who installed 29 114
Importing Special Characters in Dynamics GP Through Integration Manager 3 97
twoTwo  challenge 35 119
Line meaning 9 97
In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question