Solved

"Use MFC in static/shared" crashes for static

Posted on 1998-08-04
12
803 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
12 Comments
 

Author Comment

by:eskimo100997
Comment Utility
Edited text of question
0
 

Author Comment

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

Expert Comment

by:TangCheng
Comment Utility
 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
 

Author Comment

by:eskimo100997
Comment Utility
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
Comment Utility
Adjusted points to 300
0
 
LVL 8

Expert Comment

by:Answers2000
Comment Utility
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
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:eskimo100997
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
Great !
0
 
LVL 1

Expert Comment

by:sudhirbrat
Comment Utility
Where is my ICE CREAM !!!!!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
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 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.
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

772 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

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now