第二人生的源碼分析 3 程序入口點
阿新 • • 發佈:2019-02-02
int ptr 清空 exception 如果 pen text code 命令行
所有Windows圖形應用程序都是擁有相同的入口點函數WinMain,因此第二人生的程序也不例外。下面先來看看這個函數的代碼,如下:
//蔡軍生 2007/12/28 QQ:9073204 深圳
#001 int APIENTRY WinMain(HINSTANCE hInstance,
#002 HINSTANCE hPrevInstance,
#003 LPSTR lpCmdLine,
#004 int nCmdShow)
#005 {
#006 LLMemType mt1(LLMemType::MTYPE_STARTUP);
這行代碼主要作用就是聲明跟蹤內存分配的類型。LLMemType類統計當前使用內存大小,並且可以輸出內存的類型信息。
#007
#008 // *FIX: global
#009 gIconResource = MAKEINTRESOURCE(IDI_LL_ICON);
這行代碼主要獲取資源裏的ICON圖標句柄。
#010
#011 // In Win32, we need to generate argc and argv ourselves...
#012 // Note: GetCommandLine() returns a potentially return a LPTSTR
#013 // which can resolve to a LPWSTR (unicode string).
#014 // (That‘s why it‘s different from lpCmdLine which is a LPSTR.)
#015 // We don‘t currently do unicode, so call the non-unicode version
#016 // directly.
#017 LPSTR cmd_line_including_exe_name = GetCommandLineA();
這裏是獲取命令行參數,在Windows API一日一練裏已經介紹過,如果不懂可以參考它。
#018
#019 const S32 MAX_ARGS = 100;
#020 int argc = 0;
#021 char* argv[MAX_ARGS]; /* Flawfinder: ignore */
#022
#023 fill_args(argc, argv, MAX_ARGS, cmd_line_including_exe_name);
上面這段代碼是分析輸入的命令行參數。
#024
#025 LLAppViewerWin32* viewer_app_ptr = new LLAppViewerWin32();
這行代碼開始創建Windows窗口管理程序,也就是第二人生的管理類。
#026
#027 // *FIX:Mani This method is poorly named, since the exception
#028 // is now handled by LLApp.
#029 bool ok = LLWinDebug::setupExceptionHandler();
這行代碼實現了加載dbghelp.dll的功能,主要為了生成程序運行出錯信息報表,可以精確地定位在那個模塊裏出錯,並且把當時的環境參數全部生成報表,上傳給第二人生開發廠家,以便改正這個出錯的原因。
#030
#031 // Actually here‘s the exception setup.
#032 LPTOP_LEVEL_EXCEPTION_FILTER prev_filter;
#033 prev_filter = SetUnhandledExceptionFilter(viewer_windows_exception_handler);
這裏設置了系統異常出錯處理函數,當應用程序產生非法出錯時,就會調用這個函數來生成報表。
#034 if (!prev_filter)
#035 {
#036 llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with NULL!" << llendl;
#037 ok = FALSE;
#038 }
#039 if (prev_filter != LLWinDebug::handleException)
#040 {
#041 llwarns << "Our exception handler (" << (void *)LLWinDebug::handleException << ") replaced with " << prev_filter << "!" << llendl;
#042 ok = FALSE;
#043 }
上面這段代碼主要判斷是否設置Windows異常處理成功。
#044
#045 viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
這行代碼保存異常處理函數。
#046
#047 ok = viewer_app_ptr->tempStoreCommandOptions(argc, argv);
#048 if(!ok)
#049 {
#050 llwarns << "Unable to parse command line." << llendl;
#051 return -1;
#052 }
#053
上面保存命令行參數。
#054 ok = viewer_app_ptr->init();
#055 if(!ok)
#056 {
#057 llwarns << "Application init failed." << llendl;
#058 return -1;
#059 }
#060
調用函數init來初始化整個應用程序,比如創建線程,初始化OpenGL等等,在這個函數裏實現大部份功能的初始化。
#061 // Run the application main loop
#062 if(!LLApp::isQuitting())
#063 {
#064 viewer_app_ptr->mainLoop();
#065 }
上面第62行檢查否有退出應用程序的可能。
第64行就進入了Windows應用程序的消息處理函數,在這個函數裏實現主窗口的消息處理,還實現空閑處理,鍵盤輸入處理,接收到網絡命令,以及OpenGL渲染。
#066
#067 if (!LLApp::isError())
#068 {
#069 //
#070 // We don‘t want to do cleanup here if the error handler got called -
#071 // the assumption is that the error handler is responsible for doing
#072 // app cleanup if there was a problem.
#073 //
#074 viewer_app_ptr->cleanup();
#075 }
#076 delete viewer_app_ptr;
#077 viewer_app_ptr = NULL;
#078 return 0;
#079 }
上面這段代碼,檢查是否出錯退出,如果出錯就清空所有分配的資源。最後刪除應用程序管理類。
通過這個函數的學習,會發現第二人生的代碼寫得比較強悍的,不但出錯的處理面面具到,還具備了運行時調試信息輸出,強大的LOG系統功能。通過這個函數應學會怎麽樣添加處理系統異常出錯的方法,調試發行版的程序方法,怎麽生成具體的報表發送給軟件開發廠商的實現。
總結一下,這裏運行的流程:
1、 調用WIN API函數GetCommandLineA來獲取命令行參數。
2、 調用fill_args函數分析命令行參數。
3、 調用函數LLWinDebug::setupExceptionHandler來加載調試庫DebugHlp.dll。
4、 調用函數SetUnhandledExceptionFilter來設置新異常處理。
5、 調函數viewer_app_ptr->init來實始化管理類所有初始化工作。
6、 調用函數viewer_app_ptr->mainLoop進入Windows的消息循環處理。
7、 刪除所有分配的資源。
再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow
第二人生的源碼分析 3 程序入口點