Microsoft KB Archive/115088

= PRB: A _USRDLL with No CWinApp Object Fails to Load =

Article ID: 115088

Article Last Modified on 11/21/2006

-

APPLIES TO

 Microsoft Foundation Class Library 4.2, when used with:  Microsoft Visual C++ 1.0 Professional Edition

 Microsoft Visual C++ 1.5 Professional Edition

 Microsoft Visual C++ 1.51

 Microsoft Visual C++ 1.52 Professional Edition</li></ul>

 Microsoft Visual C++ 1.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.0 Professional Edition</li></ul>

 Microsoft Visual C++ 2.1</li></ul>

 Microsoft Visual C++ 4.0 Standard Edition</li></ul> </li></ul>

-

<div class="notice_section">

This article was previously published under Q115088

<div class="symptoms_section">

SYMPTOMS
If you build an MFC _USRDLL using Visual C++, version 1.0, without defining a CWinApp object, when its LibMain function is called you will get the following message in the debugger Output Window:

AfxAbort called

If you are using Visual C++, version 1.0 for Windows NT, you will get the following message box when DllMain is called:



If you are using Visual C++, version 1.5, you will get the following message when LibMain is called:

AfxAbort called

If you are running a Windows-based application, the call to LibMain will fail without warning, unless you are running under the debugger. Under Windows NT, you will get the warning shown previously when calling DllMain (if you are running a debug version of your DLL), followed by message boxes from the system stating that the application caused a problem.

In order to support resource-only DLLs, the assertions described above were removed in Microsoft Visual C++ 32-bit Edition, versions 2.0, 2.1, 2.2, and 4.0. Using those versions, calling a CWinApp member function through the pointer returned by AfxGetApp will result in an access violation if there is no CWinApp object defined in the DLL.

<div class="cause_section">

CAUSE
When an attempt is made to load a DLL for the first time, the DLL[ASCII 146]s entry point (LibMain for Windows, DllMain for Windows NT) is called to initialize its instance. For a _USRDLL, the entry point calls AfxWinInit, which calls AfxGetApp. If no CWinApp object has been instantiated in the DLL, AfxGetApp returns "NULL". AfxGetApp cannot access the calling application's CWinApp (if the calling application is an MFC application). This causes the assertion.

This behavior is by design, because most of the classes provided by MFC rely on the instantiation of a CWinApp object. Even some simple objects such as an AfxMessageBox make calls to AfxGetApp. If no CWinApp object exists [and your DLL uses any GUI objects that rely on calls to AfxWinInit and AfxWinTerm], assertions and program failures will occur.

<div class="resolution_section">

RESOLUTION
Be sure to instantiate an object of type CWinApp or a class derived from CWinApp. If it is important that you not have a CWinApp object in your _USRDLL, see the "MORE INFORMATION" section of this article, below, for suggestions.

NOTE: Visual C++ 4.0 automatically generates the code containing the declaration, definition, and instantiation of the CWinApp derived class for the DLL, so the following sections do not apply.

<div class="moreinformation_section">

MORE INFORMATION
It is not necessary for your DLL to call AfxWinInit and AfxWinTerm for it to use the MFC collection classes and the simple class types such as CString. If you wish to use only these MFC classes in your DLL, you can omit the instantiation of a CWinApp object, but you also must write your own LibMain or DllMain function for the DLL.

For an example of the code that you may want to include in your entry point, you can look at what MFC normally does in AfxWinInit.

NOTE: SetCurrentHandles is called, so afxCurrentInstanceHandle and afxCurrentResourceHandle get set equal to m_hInstance. You may need to set these values yourself.

Sample Code for Windows
The code below shows one possible implementation of LibMain. For the sake of pointing out the initialization portion, LibMain calls MyInit, which consists of a very simplified simulation of AfxWinInit. // Compile options needed: /D "_USRDLL"

#include <afxwin.h>

BOOL AFXAPI MyInit(HINSTANCE);

extern "C" int FAR PASCAL LibMain(HINSTANCE hInstance,     WORD wDataSegment, WORD wHeapSize, LPSTR lpszCmdLine) {     // Initialize DLL's instance(/module) not the app's      if (!MyInit(hInstance)) {        return 0;    // Init Failed }

// nothing to run return 1;  // ok   }

BOOL AFXAPI MyInit(HINSTANCE hInstance) {     afxCurrentInstanceHandle = hInstance; afxCurrentResourceHandle = hInstance;

// one instance initialization stuff goes here

// Handle critical errors ::SetErrorMode(SEM_FAILCRITICALERRORS);

return TRUE; }

Sample Code for Windows NT
The code below shows one possible implementation of DllMain. For the sake of pointing out the initialization portion, DllMain calls MyInit, which consists of a very simplified simulation of AfxWinInit. // Compile options needed: /D "_USRDLL"

#include <afxwin.h>

BOOL AFXAPI MyInit(HINSTANCE);

extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {          if (dwReason == DLL_PROCESS_ATTACH) {                  // Initialize DLL's instance(/module) not the app's                   if (!MyInit(hInstance)) {                          return 0;       // Init Failed }

}          return 1;   // ok   }

BOOL AFXAPI MyInit(HINSTANCE hInstance) {          afxCurrentInstanceHandle = hInstance; afxCurrentResourceHandle = hInstance;

// one instance initialization stuff goes here

// Handle critical errors ::SetErrorMode(SEM_FAILCRITICALERRORS);

return TRUE; }

Additional query words: 1.00 1.50 2.00 2.10 2.50 4.00

Keywords: kbdll kbprb KB115088

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.