RAND_poll函数在Windows下存在的问题

RAND_poll函数是OpenSSL中用于初始化伪随机数生成器的函数,当首次调用诸如RAND_bytes等需要生成随机数的函数时,会先调用该函数进行初始化。在实际使用中发现,RAND_poll函数在Windows下存在一些问题,需要小心提放,否则可能会对程序造成不良影响。

创建一个最简单的Windowless RichEdit

RichEdit是Windows上很常用的富文本控件,它有一个无窗口化的版本,即Windowless RichEdit,关于它的介绍,可以参考官方文档:https://msdn.microsoft.com/en-us/library/windows/desktop/bb787609(v=vs.85).aspx 。Windowless RichEdit与普通RichEdit在行为表现上毫无二致,但是在使用方法上却有较大的差异;而且Windowless RichEdit的官方文档少之又少,说明不够全面,甚至连一个完整的示例也没有;更甚者,在不同的Windows平台和开发环境下,Windowless RichEdit的用法都有差异。这让初次接触Windowless RichEdit的人举步维艰,处处碰壁,正应了“万事开头难”这句话。因此,本文聚焦于“开头”,介绍一下创建一个最简单的Windowless RichEdit需要做哪些事情。

WM_TIMER消息是否会在消息队列中堆积

在Windows界面开发中,启动定时器的最常用方法是使用SetTimer这个API。通过这个API启动的定时器会持续不断地往窗口消息队列中投递WM_TIMER消息,直到调用了KillTimer来停止。一个有趣的问题是,假如定时器的消息程序处理不过来,即处理WM_TIMER的时间比定时器的间隔时间长,会发生什么事情呢?消息队列中是否会堆积越来越多的WM_TIMER消息?官方文档中并没有指出这个问题,只能通过实践来找出答案。

如何让std::shared_ptr持有IUnknown对象

C++11新增的智能指针std::shared_ptr使用引用计数来管理对象的生命周期,而COM提供的IUnknown接口也使用引用计数来管理自身的生命周期。理论上来说,在同一个环境中不应该同时使用两套引用计数方案,不然会造成混乱,带来很多麻烦。然而实际上,需要同时使用这两种方案的情况并不少见,有时的确需要用std::shared_ptr来持有COM对象。虽然这种做法看上去丑陋,并且是可以用别的方法来避免的,但本文不讨论这些方面,只聚焦于问题的本身。

如何调试在std::thread子线程中抛出的C++异常

C++11标准库新增的std::thread类可以方便地开启子线程。然而有个奇怪的现象是,如果在这些子线程中抛出了未处理的C++异常而导致程序崩溃,那么在生成的dump文件中将还原不出异常发生时的调用栈。可以通过下面的方法来展示这个现象。

使用预编译头提高编译速度

什么是预编译头

在介绍预编译头之前,有必要了解一下C/C++的编译方式。C/C++的编译单元是源文件(带有.c、.cc、.cpp等扩展名的文件),在编译一个源文件之前,预处理器会把这个源文件中所有通过#include指令包含进来的头文件递归地展开,也就是把所有直接或间接包含的头文件原封不动地插入进来。当这个过程结束之后,才开始编译。

使用流式输出写调试日志

日志是一种有效的调试手段。但是日志写得太频繁会降低程序性能,所以一般采取的策略是,大部分日志只在调试版的程序中输出,少量重要的日志才在发行版的程序中输出。为了控制调试日志的输出,通常会使用下面的简便方法: