可能有人也碰到了向我一样的问题,那就是在多字节版本下的一个windows程序,但是在unicode版本下却会出现崩溃。崩溃的位置是在__tmainCRTStartup还是中。先看看mfc的启动流程吧。下面流程部分是转载的。
<textarea cols="87" rows="17" name="code" class="cpp">MFC封装了WIN API.大家都知道.但是MFC应用程序的真正流程又有多少人知道呢? 下面就是我对MFC启动代码的一些剖析. 在TCHAR.H里,有这么2小段define.通过我的简化,我们可以看到: //TCHAR.H #ifdef _UNICODE #define _tWinMain wWinMain #else #define _tWinMain WinMain #endif 由于为了支持UNICODE,C运行库对WinMain其实区分了UNICODE版和ANSI版.对UNICODE版的程序,C运行库将调用wWinMain,而对于ANSI版的应用,则调用WinMain.这是第一点. 然后,其实MFC的代码设计时是自动支持UNICODE的,所以,MFC的WinMain在APPMODUL.CPP被定义为 _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) 这样以一来,无论用户#define _UNICODE与否,MFC的WinMain都会被调用.接下来,_tWinMain的实际运作如下: extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // call shared/exported WinMain return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } 这样,AfxWinMain就和MFC挂上了钩.甚至在PETER NORTON的书中,都仅讲到了AfxWinMain乃是MFC的WinMain,但是,NORTON同志看来没有讲述清楚这点.因为,WinMain仍然是WinMain,C运行库并没有因为MFC的存在而重新设计AfxWinMain的入口. 在MS的AfxWinMain(WINMAIN.CPP)里我们可以看到如下代码: int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { ASSERT(hPrevInstance == NULL); int nReturnCode = -1; CWinThread* pThread = AfxGetThread(); CWinApp* pApp = AfxGetApp(); // AFX internal initialization if (!AfxWinInit(hInstance, hPrevInstance, lpCmdLine, nCmdShow)) goto InitFailure; // App global initializations (rare) if (pApp != NULL && !pApp->InitApplication()) goto InitFailure; // Perform specific initializations if (!pThread->InitInstance()) { if (pThread->m_pMainWnd != NULL) { TRACE0("Warning: Destroying non-NULL m_pMainWndn"); pThread->m_pMainWnd->DestroyWindow(); } nReturnCode = pThread->ExitInstance(); goto InitFailure; } nReturnCode = pThread->Run(); InitFailure: #ifdef _DEBUG // Check for missing AfxLockTempMap calls if (AfxGetModuleThreadState()->m_nTempMapLock != 0) { TRACE1("Warning: Temp map lock count non-zero (%ld).n", AfxGetModuleThreadState()->m_nTempMapLock); } AfxLockTempMaps(); AfxUnlockTempMaps(-1); #endif AfxWinTerm(); return nReturnCode; } 以上代码将整个庞大的MFC架构完全启动起来.如果要了解其Afx大头的函数群,大家可以对以看一下MFC源代码里的*CORE.CPP. 真正的难点到是到TCHAR.H中找到WinMain的别名吧.因为几乎没人会想到TCHAR.H居然隐藏了如此大的MFC机要啊... </textarea>
可以再在启动的过程进行一步步跟踪查看执行过程。断点就下在WinMainCRTStartup,然后一步步来,就行了。
在ansi中,调用_tWinMain时,直接到了我们自己的WinMain函数中,但是在Unicode下面怎么就不行了呢。 按照ms给的解决方案:http://support.microsoft.com/kb/125750。 把连接器-》高级-》入口点改成wWinMainCRTStartup之后,还是和之前一样,进入了mfc给的一个函数_tWinMain中。之后就会在AfxGetThread和AfxGetApp中得到空。最后就是崩溃了。这是为什么呢?再看看上面的流程,以及跟踪的过程知道,_tWinMain是一个宏,这也就是说,有可能没有找到正确的入口点位置。于是,我就选项中的入口点删除,重新运行,一切ok。就这么简单。