"Use MFC in static/shared" crashes for static

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,

Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

sudhirbratConnect With a Mentor Commented:
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.
eskimo100997Author Commented:
Edited text of question
eskimo100997Author Commented:
An Ice cream is offered to the first who finds the solution !
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 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.
eskimo100997Author Commented:
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.
eskimo100997Author Commented:
Adjusted points to 300
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.
eskimo100997Author Commented:
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.
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
eskimo100997Author Commented:
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.
eskimo100997Author Commented:
Great !
Where is my ICE CREAM !!!!!
All Courses

From novice to tech pro — start learning today.