文档化说明的重要性

用通过下面的两个示例,来说明官方给出的文档化说明的重要性。一个是MSDN上给出的说明,一个是GDIView GDI泄漏检测工具官方给出的说明。以这些官方说明为线索,可以找到我们程序出问题的地方,进而将问题解决掉。

1、聊天服务器时间的本地时区和夏时令的问题

(1)TL的聊天时间使用服务器时间,TL底层的XMPP客户端需要和服务器时间进行同步,进而获取服务器时间,用于聊天信息的时间戳。服务器传递过来的是UTC+0的时间,是字符串格式的年月日时间,不是整数时间。XMPP客户端要使用时差bias、mktime和localtime等将字符串年月日时间转换成UTC+0的整数时间,在发送消息时,将整数时间转成字符串年月日时间,发送给对端。接收端接收到消息时,将字符串年月日时间转换成整数时间,填充到消息结构体中供上层使用。

(2)收到服务器时间请求的回应时,将收到的字符串年月日时间转换成整数时间,如下所示:

后来确认是转换过程中多出了1个小时。当时的测试环境是:发送端设置UTC+10的带夏时令的时区,如下:

发送端:发送端发出消息后,收到终端层的消息发送的rsp,rsp中携带服务器时间,显示框中显示就是这个返回的服务器时间,比本地时间多了一个小时,

接收端:接收端接收到消息后,消息中携带了发送时的服务器时间,接收端转换出来的本地时间也多了一个小时,按讲接收端收到消息后也用了mktime,应该是多了两个小时才对啊?哈哈,接收端当时设置的是UTC+8的北京时区,没有夏时令调整的,所以接收端只多了一个小时。

(3)发送端发送消息时,构建UTC+0字符串年月日时间,如下:

接收端收到消息时,将UTC+0字符串年月日时间转成整数时间,如下:

(4)为定位问题,查看mktime函数的实现:

那么dstbias是如何实时get来的呢?因为用户可能中途改变了时区,涉及到有夏时令的,dstbias就不是默认的-3600了,相关代码如下:

由上述代码可知,在__tzset内部调用GetTimeZoneInfomation,实时的计算了dstbias的值,但是程序启动后,再改变时区,是不会实时更新dstbias等值的,即只在启动后第一次调用mktime时才会调用GetTimeZoneInfomation,实时获取dstbias等值。

(5)在asctime函数说明找到对struct  tm的说明,如下:

(6)多一个小时问题的定位:

经调试发现,在设置下面的时区后,dstbias为-3600,正好一个小时

是下面代码的问题,是memset的问题:

即tTime.tm_isdst为0,进入不了上面的分支,多余的一个小时没有减掉,所以多了一个小时。

(7)VS2008的MSDN中对tm_isdst字段的说明不太清楚,如下:

但是最新的网页上的MSDN中说明的很清楚,如下:(所以再一次说明,遇到VS2008MSDN上讲的不清楚或者不明白的问题时,不妨到MSDN网站上查看一下最新的说明,说不定会有我们需要的帮助说明

通过查看mktime的内部实现,里面调用了_localtime64_s和_gmtime64_s函数,在这两个函数中,都有struct tm结构体的初始化,都初始化0xFF,

即将tm的结构体的tm_isdst设置为0xFF,即小于0,由运行时库内部决定是否将夏时令时间dstbias,这样初始化XMPP侧的时间处理就没问题了。对于CTime类而言,也有参考的,传入的年月日时间参数时的构造函数,如下,最后的是否考虑夏时令也是传递的负值:

(8)时间处理函数mktime、localtime、gmtime函数和CTime类的说明:

mktime:将tm结构体时间转换成整数时间,会减去对UTC+0的时差值bias绝对值;

localtime:将整数时间转换成tm结构体时间,会加上对UTC+0的时差值bias绝对值;

gmtime:将整数时间转换成tm结构体时间,不进行时差的处理;

CTime类:

传入的整数值是UTC+0的整数时间。

由(7)中的代码得知,如果传入本地时区的年月日时间,在内部要经过mktime,转换成UTC+0整数时间的。

CTime的多个方法都是mktime、localtime的封装,参照这些函数的转换即可。

2、无从下手的GDI资源泄漏问题

(1)新版TL中打开部分窗口后关闭,GDI句柄数每次都上升6个,即有GDI资源泄漏。按讲打开的窗口销毁后,GDI相关资源都会销毁,这就比较奇怪了。由于部分窗口在打开关闭后没有泄漏,对比了一下,暂时可以考虑directui库没有泄漏问题。通过GDIView观察,GDI
Total列没有增长,All GDI列每次都有增长。
这就比较奇怪了,一般我们的资源泄漏主要是pen、bitmap等,结果这次这些常规GDI对象没有泄漏,感觉无从查起了。

(2)于是尝试着到GDIView的官网上查看一下,结果找到了对应的说明,如下:

官网:http://www.nirsoft.net/utils/gdi_handles.html

由上述可知,出现GDI Total列没有增长,All GDI列有增长的原因可能是图标资源或者光标资源在创建后没有释放引起的。于是乎想到,部分窗口在关闭后没有GDI句柄上升的情况,仔细想了一下,这些窗口都没有任务栏窗口,都没有设置icon图标。

(3)于是找到设置图标的代码,如下:

这个函数中只用到了LoadImage,到msdn上查看LoadImage的说明,找到了可能存在icon资源泄漏的情况,如下:

也就是说,使用LoadImage时如果没有设置LR_SHARED标记,则需要手动去Destroy掉这些资源,否则会导致泄漏。于是添加了LR_SHARED标记,修改后的代码如下:

最后再用GDIView查看,就没有GDI资源泄漏了。

时间: 2024-11-20 11:55:00

文档化说明的重要性的相关文章

使用Xcode HeaderDoc和Doxygen文档化你的Objective-C和Swift代码

在一个应用的整个开发过程中涉及到了无数的步骤.其中一些是应用的说明,图片的创作,应用的实现,和实现过后的测试阶段.写代码可能组成了这个过程的绝大部分,因为正是它给了应用生命,但是这样还不够,与它同等重要的还有代码的注释和文档编写.不管代码写的有多好,如果缺少了对应的好的注释文档,很有可能在将来带来麻烦.不幸的是,许多开发者都忽视或忽略了代码文档的重要性,而这非常糟糕,因为好的程序不仅仅是好的代码.它需要更多的东西. 谈到编写注释文档,显然我不是说仅仅简单的在实现文档里添加几行注释.肯定是更多的东

使用 Swagger 文档化和定义 RESTful API

大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Services Description Language,WSDL)类似的语言来定义使用者与提供者之间的请求和响应结构.由于没有充分的合同服务,许多 REST API 提供者使用 Microsoft Word 文档或维基页面来记录 API 用法.这些格式使协作和文档版本控制变得很困难,尤其对于有许多 API 或资源的应用程序,或者

利用未文档化API:RtlAdjustPrivilege 提权实现自动关机

这里主要是利用NTDLL.dll中未文档化的API: RtlAdjustPrivilege 来实现提权.自动关机的功能. RtlAdjustPrivilege定义如下: NTSTATUS RtlAdjustPrivilege ( ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled ) 参数含义如下:Privilege [In] Privilege index to change.            

UML是文档化的语言

 The UML Is a Language for Documenting A healthy software organization produces all sorts of artifacts in addition to raw executable code. These artifacts include (but are not limited to) Requirements Architecture Design Source code Project plans T

Qt的自文档化工具qdoc

在<人月神话>一书中,提及了软件工程中必备的一个概念:自文档化.所谓自文档化,就是把文档和代码合二为一,既增强了文档的可维护性,又增强了代码的可读性,一举两得,何乐而不为呢? 在Qt开发中,就有这样的自文档化工具:qdoc.使用qdoc,通常分三步走. 第一步,添加QDoc注释到必要的.cpp文件或.qdoc文件,在.h文件中添加QDoc注释是无效的. 第二步,编辑.qdocconf配置文件. 第三步,运行qdoc,默认生成HTML文档,命令如下: $xxx/bin/qdoc ./config

突发奇想之:源码及文档,文档包括源码---xml格式的源码,文档源码合并;注释文档化,文档代码化;

目前源码和文档一般都是分开的,我在想为什么 源码不就是最好的文档么? 但是一般源码都是文本text的,格式化需要人为统一规范,所以源码中的文档在现实中不是那么的易于实践. 而且 源码 不能包括图片.附件.示例代码等资源,这个又是一个难点. 后来我突发奇想,为什么不能把xml作为一种合二为一的文档呢? xml可被IDE识别,解析其中 包括 <code lang=cpp> 的标签中的文本为 代码.编译也使用这部分. 其他的标签 全部都是文档.而且可以在code 代码中 再分割,添加文档部分. 而文

NTDLL未文档化函数RtlGetNtVersionNumbers获取操作系统版本

作为新手,对获取操作系统版本号好奇过,因为曾经假象过一个场景:如果将来在windows xp环境下编译的程序,在windows xp跑会怎样, 在windows 2003,windows 7,windows 8又会怎样,如果程序在windows 7以上版本需要特殊处理又该怎样判断操作系统版本呢. 带着这个好奇也了解过GetVersion和GetVersionEx函数,他们的最低使用需求是Windows 2000,以下是一些官方的测试代码. GetVersion function #include

Swagger文档化restful接口

1.注解 @Api:用在类上,说明该类的作用. @ApiOperation:注解来给API增加方法说明. @ApiImplicitParams : 用在方法上包含一组参数说明. @ApiImplicitParam:用来注解来给方法入参增加说明. @ApiResponses:用于表示一组响应 @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息 l   code:数字,例如400 l   message:信息,例如"请求参数没填好" l   resp

软件测试文档

在软件测试中的流程中,测试文档也是一个重要的流程,所以测试人员也需要学习测试文档的编写和阅读. 一.定义: 测试文档(Testing Documentation)记录和描述了整个测试流程,它是整个测试活动中非常重要的文件.测试过程实施所必备的核心文档是:测试计划.测试用例和软件测试报告. 二.测试文档的重要性 软件测试是一个很复杂的过程,涉及软件开发其他阶段的工作,对于提高软件质量.保证软件正常运行有着十分重要的意义,因此必须把对测试的要求.过程及测试结果以正式的文档形式写下来.软件测试文档用来