所有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、             删除所有分配的资源。

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

  1. Linux内核源码分析方法—程序员进阶必备

    一.内核源码之我见 Linux内核代码的庞大令不少人"望而生畏",也正因为如此,使得人们对Linux的了解仅处于泛泛的层次.如果想透析Linux,深入操作系统的本质,阅读内核源码是 ...

  2. 第二人生的源码分析(二十六)底层网络协议

    为了理解第二人生的客户端与服务器的沟通,那么下面就来分析一下第二人生采用的网络协议.在目前的网络里,主要有两个协议:TCP和UDP,而第二人生里是采用UDP协议.TCP协议与UDP协议的主要区别,就是 ...

  3. MYC编译器源码分析之程序入口

    前文.NET框架源码解读之MYC编译器讲了MyC编译器的架构,整个编译器是用C#语言写的,上图列出了MyC编译器编译一个C源文件的过程,编译主路径如下: 首先是入口Main函数用来解析命令行参数,读取 ...

  4. 精尽 Redisson 源码分析 —— 可重入分布式锁 ReentrantLock

    1. 概述 在 Redisson 中,提供了 8 种分布锁的实现,具体我们可以在 <Redisson 文档 -- 分布式锁和同步器> 中看到.绝大数情况下,我们使用可重入锁(Reentra ...

  5. 第二人生的源码分析(102)脚本的构造

    前面我们学习怎么样打开窗口来创建脚本,接着下来就需要知道这些脚本是做什么用的,这样最终才会按它的语义来正确地执行起来. 现在我们能够查看脚本的内容: default { state_entry() { ...

  6. dolphinscheduler-数据质量-源码分析

    数据质量工作流程 数据质量运行流程分为2个部分:在web端进行数据质量检测的流程定义,通过dolphinscheduer进行调度,提交到spark计算引擎:spark端负责解析数据质量模型的参数,通过 ...

  7. spark源码分析之Broadcast

    Broadcast简介&使用 在Spark程序中,经常会遇到算子函数中使用较大的外部变量的场景.由于在算子函数中使用到外部变量时,默认情况下,Spark会将该变量复制多个副本,通过网络传输到t ...

  8. 一个简单的IPmsg程序源码分析(二)

    离上篇一个简单的IPmsg程序源码分析(一)已经基本半个月(上篇最初发布在点点上面,后边纠结了一下还是选择了博客园),利用空闲的时间终于把源码的构架和一些细节基本都搞清楚了,总的来说是很简单的一个客户 ...

  9. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  10. 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )

    文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...

最新文章

  1. webpack源码之tapable
  2. 底盘编码数据解算ROS的odom数据
  3. lzma打包exe_Web 项目打包EXE
  4. Shell中的Wget 的用法
  5. “达克效应”让人们信心满满还是畏惧不前?- 更应该是谨慎地冒险
  6. 关于html:form/html:form特性
  7. ubuntu mysql环境变量配置_MySQL在Win10与Ubuntu下的安装与配置
  8. so easy 的弹出层——使用jquery
  9. php提取文本数据处理,PHP文件处理—读取文件(一个字符,字串)
  10. 二级c语言笔试57,二级C语言笔试真题与答案.doc
  11. jdk下载/Linux64位 jdk1.8 jdk-8u161下载
  12. Golang实战【IP池-自动切换IP爬虫】
  13. “IndentationError: unindent does not match any outer indentation level“ 错误解决
  14. 如何能从自我怀疑中走出来?
  15. 软件测试人员,究竟怎么霸气过七夕?!大神攻略请笑纳!
  16. SQL字符串首字母大写
  17. 支持向量机SVM--线性
  18. 域名注册条件有哪些?需要提交哪些材料?
  19. 教你30元自制考勤打卡系统!
  20. 生活娱乐 如何给女朋友写情书

热门文章

  1. 小米平板2刷android,小米平板2怎么刷回MIUI 小米平板2刷回MIUI教程
  2. 天龙八部科举答题问题和答案(全3/8)
  3. 9月9日资讯 星期四 农历八月(小) 初三
  4. python切换环境_python如何变换环境
  5. Gitee + Hexo 搭建个人博客
  6. 《异度神剑2》与柏拉图的精神世界略考(上)
  7. LED设备驱动开发实验—源码代码详解
  8. 转换pdf异常The document appears to be corrupted and cannot be loaded解决
  9. 000001 Kick off
  10. 平板电脑可以用手写的计算机软件,平板电脑可以当手写板(绘图板)用吗?