Solved

Assertion in appcore.cpp - why?

Posted on 2012-12-24
15
1,977 Views
Last Modified: 2013-01-09
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.
0
Comment
Question by:tullhead
  • 6
  • 5
  • 3
  • +1
15 Comments
 
LVL 28

Expert Comment

by:pepr
Comment Utility
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.
0
 

Author Comment

by:tullhead
Comment Utility
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?
0
 
LVL 86

Expert Comment

by:jkr
Comment Utility
Stupid question - does a Release Build work as expected?
0
 
LVL 28

Expert Comment

by:pepr
Comment Utility
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?
0
 

Author Comment

by:tullhead
Comment Utility
jkr -- also dies immediately when built in Release mode.
0
 
LVL 32

Expert Comment

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

Author Comment

by:tullhead
Comment Utility
Sara --

Yes, I have all that.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 28

Assisted Solution

by:pepr
pepr earned 200 total points
Comment Utility
Are you sure you are using a single instance of the CWinApp (or its subclass)? You can have only one, globally accessible instance. You can try to put a breakpoint to the beginning of the constructor body to see whether you pass it only once.
0
 
LVL 32

Accepted Solution

by:
sarabande earned 200 total points
Comment Utility
to add to pepr's comment:

you told above that the static library has a definition for a subclass of CWinApp. if so, then it is a second instance to the one you have in your mfc app project. when the second instance was passing the constructor CWinApp::CWinApp you may get the assertion.  

to solve the issue you need to remove or comment the definition in the souce containing to the static library.

Sara
0
 
LVL 32

Expert Comment

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

Author Comment

by:tullhead
Comment Utility
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?
0
 

Author Comment

by:tullhead
Comment Utility
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?
0
 
LVL 32

Expert Comment

by:sarabande
Comment Utility
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
0
 
LVL 32

Expert Comment

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

Author Closing Comment

by:tullhead
Comment Utility
Thanks -- I'l split the points -- Sara you helped a lot but Pepr's statement to place a breakpoint made me do it....
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to synchronize PHP projects with a remote server in NetBeans IDE 8.0 for Windows.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

763 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

6 Experts available now in Live!

Get 1:1 Help Now