"Use MFC in static/shared" crashes for static

Posted on 1998-08-04
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:

      { 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;


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

      return TRUE;

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

CFtpDebugDlg::CFtpDebugDlg(CWnd* pParent /*=NULL*/)
      : CDialog(CFtpDebugDlg::IDD, pParent)
            // NOTE: the ClassWizard will add member initialization here
      // 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,

Question by:eskimo100997

Author Comment

ID: 1320212
Edited text of question

Author Comment

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

Expert Comment

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.
Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.


Author Comment

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.

Author Comment

ID: 1320216
Adjusted points to 300

Expert Comment

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.

Author Comment

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.
LVL 11

Expert Comment

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

Author Comment

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.

Accepted Solution

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...


Try this and let me know the result.

Author Comment

ID: 1320222
Great !

Expert Comment

ID: 1320223
Where is my ICE CREAM !!!!!

Featured Post

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Suggested Solutions

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
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.

786 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