Avatar of tullhead
tullhead
Flag for United States of America asked on

Assertion in appcore.cpp - why?

My MFC App dies right away when started, due to ASSERT in the CWinApp constrcutor.  It dies in the last line of this snippet:

CWinApp::CWinApp(LPCTSTR lpszAppName)
{
      if (lpszAppName != NULL)
            m_pszAppName = _tcsdup(lpszAppName);
      else
            m_pszAppName = NULL;

      // initialize CWinThread state
      AFX_MODULE_STATE* pModuleState = _AFX_CMDTARGET_GETSTATE();
      ENSURE(pModuleState);
      AFX_MODULE_THREAD_STATE* pThreadState = pModuleState->m_thread;
      ENSURE(pThreadState);
      ASSERT(AfxGetThread() == NULL);

Now, my exe contains a built in static lib, and that static lib has in it a definition of a CWinApp subclass.  My confusion may also be conflated with the fact that I just made the leap from IDE 6.0 up to VS 2010 and I may be doing something wrong with linking in the static library.    Can someone point me where to look or give a hint as to what is likely wrong?  Thanks.
C++Editors IDEs

Avatar of undefined
Last Comment
tullhead

8/22/2022 - Mon
pepr

Apparently, you expect the AfxGetThread() returns NULL. However, there is the following note in the official documentation (http://msdn.microsoft.com/en-us/library/0aa1ya36%28v=vs.100%29.aspx):
If you are porting an MFC project calling AfxGetThread from Visual C++ versions 4.2, 5.0, or 6.0, AfxGetThread calls AfxGetApp if no thread is found. In Visual C+ .NET and later, AfxGetThread returns NULL if no thread was found. If you want the application thread, you must call AfxGetApp.

You should probably check your expectations with the new version of Visual Studio, and fix the assert.
tullhead

ASKER
This ASSERT is in appcore.cpp which is part of MFC (I suppose).  So, I can't (or shouldn't) go and change an assert inside part of MFC, right?   So, what should I really do to get around this issue?
jkr

Stupid question - does a Release Build work as expected?
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
pepr

Firstly, I am ATL oriented, and I did not use MFC. However, when new version of Visual Studio is used, it upgrades the solution file and namely the projects. To make the majority of older projects working the same way the older compiler did, it may use the older libraries, and sources.

Can you check whether the appcore.cpp is the part of MFC that comes with the new Visual Studio 2010?
tullhead

ASKER
jkr -- also dies immediately when built in Release mode.
sarabande

do you have an application class derived from CWinApp? and did you create an instance of that class in one of your cpp files?

and that static lib has in it a definition of a CWinApp subclass

the instance of the application class may not be defined in the static library. it needs to be in the cpp file for your application class which must be a file of the mfc app project.

// myapp.cpp
#include "stdafx.h"
#include "myproject.h"
....
// the one and only application instance
MyApp theApp;

...
MyApp::MyApp()
{
    ....
}

Open in new window


Sara
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
tullhead

ASKER
Sara --

Yes, I have all that.
SOLUTION
pepr

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
ASKER CERTIFIED SOLUTION
sarabande

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
sarabande

fyi:

the AfxGetThread() must return NULL in the CWinApp constructor cause the current thread for the instance was not yet completely created. if it doesn't return NULL there already was an application instance.

in case of a regular mfc dll, the dll has contrary to an extension dll (and of course also contrary to a static library) an own instance of the application object (which works as a proxy to the original object) but cause the dll is a separate executable the AfxGetThread nevertheless would return NULL in that case.

Sara
tullhead

ASKER
OK - I put a breakpoint on CwinApp::CWinApp and it hits it once when the main exe starts, then hits it a second time for the static DLL, and then dies in that call.  So.... I guess I've used dynamic DLLs in the past, and they have always had a CWinApp subclass object.  But, for this statically linked DLL, I cannot have one?
Your help has saved me hundreds of hours of internet surfing.
fblack61
tullhead

ASKER
I modified my "static DLL" and made the "theApp" class there not a subclass oc CWinApp, and I had to comment out the message map stuff.   Nowwhen linked with my exe it all seems to work.   Have I done the right thing?    Seems kinda messy -- is this the "standard way" to convert a dynamic DLL to a statically-linked one?
sarabande

actually there is no statically linked dll. dll means dynamic link library and static is contrary to dynamic.

a static library in vc++ means only that you put a bunch of object modules (*.obj files) into an own file which usual has a .lib file extension. another project now could link against that library and has all object modules linked same as if each single cpp (or c) file was compiled with the own project build.

because of this the second application instance from the static library was inserted to the executable additionally to the already existing one what was not tolerated at runtime cause each executable may have only one application object.

your static library should not have an application class object at all. instead it could access the one and only application object by calling AfxGetApp(). that returns a pointer to CWinApp which safely could be casted (dynamic_cast or c cast) to the derived application class.

Sara
sarabande

alternatively to calling (and casting) AfxGetApp() you also could include a header where theApp was declared as extern.

// myapp.h
...

class MyApp :: public CWinApp
{
    ...
};

extern MyApp theApp;

Open in new window


you may search your headers if there isn't already such a declaration.

the "extern" keyword would allow to declare the global variable in a header which was included by multiple cpp files. the variable then was "defined" only once in the cpp file for the application class. otherwise the linker would complain because of duplicate symbols. but you could use the variable everywhere you included the header where the variable was declared as extern. actually you not even need to include a header but also could add the extern declaration to the cpp file where you want to use the variable.

Sara
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
tullhead

ASKER
Thanks -- I'l split the points -- Sara you helped a lot but Pepr's statement to place a breakpoint made me do it....