[转载]触发ASSERT(afxCurrentResourceHandle != NULL)错误的原因

 

触发ASSERT(afxCurrentResourceHandle != NULL)错误的原因

Debug Assert error afxwin1.inl line:22

翻译参考 http://wenku.baidu.com/view/146a503987c24028915fc3f6.html

上述错误出现的原因有两个情况,一是对于控制台程序,使用MFC却没有初始化;二是使用MFC编写dll,对导出函数没有响应的宏声明。

一是对于控制台程序,使用MFC却没有初始化;

==================================================================================

 AfxWinInit

BOOL AFXAPI AfxWinInit( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )

Parameters

hInstance

The handle of the currently running module.

hPrevInstance

A handle to a previous instance of the application.  For a Win32-based application, this parameter is always NULL.

lpCmdLine

Points to a null-terminated string specifying the command line for the application.

nCmdShow

Specifies how the main window of a GUI application would be shown.

Remarks

This function is called by the MFC-supplied WinMain function, as part of the initialization of a GUI-based application, to initialize MFC. For a console application, which does not use the MFC-supplied WinMain function, you must call AfxWinInit directly to initialize MFC.

If you call AfxWinInit yourself, you should declare an instance of a CWinApp class. For a console application, you might choose not to derive your own class from CWinApp and instead use an instance of CWinApp directly. This technique is appropriate if you decide to leave all functionality for your application in your implementation of main.

The sample shows how to make a console application using MFC.

Example

// this file must be compiled with the /GX and /MT options: // cl /GX /MT thisfile.cpp

#include <afx.h>

#include <afxdb.h>

#include <iostream.h>

int main(){

 // try to initialize MFC

if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))

 { cerr << "MFC failed to initialize!" << endl; return 1; }

 // try to connect to an ODBC database that doesn't exist

 // (this wouldn't work at all without initializing MFC)

CDatabase db;

 try { db.Open("This Databsae Doesn't Exist");

 // we shouldn't realistically get here

cout << "Successful!" << endl; cout << "Closing ... ";

 db.Close();

cout << "Closed!" << endl; }

catch (CDBException* pEx) {

 // we got an exception! print an error message

// (this wouldn't work without initializing MFC)

 char sz[1024]; cout << "Error: ";

if (pEx->GetErrorMessage(sz, 1024)) cout << sz; else cout << "No error message was available";

 cout << endl; pEx->Delete();

 return 1;

}

return 0;

}

二是使用MFC编写dll,对导出函数没有响应的宏声明。

========================================================================================

ASSERT(afxCurrentResourceHandle != NULL);出现错误的完美解决办法,其实vc中已经提示说明。

 

// Note!
//
//  If this DLL is dynamically linked against the MFC
//  DLLs, any functions exported from this DLL which
//  call into MFC must have the AFX_MANAGE_STATE macro
//  added at the very beginning of the function.
//
//  For example:
//
//  extern "C" BOOL PASCAL EXPORT ExportedFunction()
//  {
//   AFX_MANAGE_STATE(AfxGetStaticModuleState());
//   // normal function body here
//  }
//
//  It is very important that this macro appear in each
//  function, prior to any calls into MFC.  This means that
//  it must appear as the first statement within the 
//  function, even before any object variable declarations
//  as their constructors may generate calls into the MFC
//  DLL.
//
//  Please see MFC Technical Notes 33 and 58 for additional
//  details.

 

 AFX_MANAGE_STATE

AFX_MANAGE_STATE( AFX_MODULE_STATEpModuleState )

Parameters

pModuleState

A pointer to an AFX_MODULE_STATE structure.

Remarks

Call this macro to protect an exported function in a DLL. When this macro is invoked, pModuleState is the effective module state for the remainder of the immediate containing scope. Upon leaving the scope, the previous effective module state will be automatically restored.

The AFX_MODULE_STATE structure contains global data for the module, that is, the portion of the module state that is pushed or popped.

By default, MFC uses the resource handle of the main application to load the resource template. If you have an exported function in a DLL, such as one that launches a dialog box in the DLL, this template is actually stored in the DLL module. You need to switch the module state for the correct handle to be used. You can do this by adding the following code to the beginning of the function:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

This swaps the current module state with the state returned from until the end of the current scope.

 

 

 这种错误的原因是由于要使用MFC库中的某些资源,但是MFC并没有被初始化.

 

 这种情况多发生在atl和其它非MFC工程,后追加MFC的头文件获得了部分支持

现象:1) 编译可以通过 2)有些MFC类可以使用  3) 使用CRectTracker, CMenu.LoadMenu....时出现触发ASSERT(afxCurrentResourceHandle != NULL)错误

 

解决办法:

在模块初始化后,要使用的MFC类前,添加如下代码:

 

 //MFC初始化
   if(!AfxWinInit(::GetModuleHandle(NULL),NULL,::GetCommandLine(),0))
   {
     return 1;
   }

转自:http://blog.csdn.net/genaman/article/details/3970982
posted @ 2014-07-26 14:37  苏轶然  阅读(915)  评论(0编辑  收藏  举报