第二人生的源码分析(3)程序入口点

所有 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、             删除所有分配的资源。
 
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值