最近要用到 libeay32.lib、ssleay32.lib 两个静态库文件,因为以前项目中其中一个文件在 64 位编译时选择的不是 MTd,而导致我引入该库以后提示运行时库和其他库声明冲突,其实实际原因就是生成选项不一样。最终我还是决定自己编译 openssl 的库来使用。

下载所需工具

准备工作

安装 Perl 和 NASM,默认下一步下一步就可以了。Perl 安装的时候记得勾选将执行程序添加到系统环境变量中。NASM 安装时没有选项,需要在完成后要将执行程序添加到系统的环境变量中。如下图所示:

解压 openssl-1.0.2p.tar.gz 到任意目录,比如 D:\openssl-1.0.2p

开始编译

打开 VS 的命令行工具(我这里安装的是 VS2013),所以目录在 C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\Shortcuts 下,如果想编译 32 位的静态库就使用 VS2013 x86 本机工具命令提示,如果想编译 64 位,就使用 VS2013 x64 本机工具命令提示

打开后切换到 D:\openssl-1.0.2p 目录,执行如下命令生成 makefile 文件。

perl configure VC-WIN32

如果是生成 64 位则执行

perl configure VC-WIN64A

成功后如下所示:

如果你要编译 debug 版本,则修改 ms/do_nasm.bat 文件,将原来

perl util\mkfiles.pl >MINFO
perl util\mk1mf.pl nasm VC-WIN32 >ms\nt.mak
perl util\mk1mf.pl dll nasm VC-WIN32 >ms\ntdll.mak
perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak

perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def

修改为:

perl util\mkfiles.pl >MINFO
perl util\mk1mf.pl nasm debug VC-WIN32 >ms\nt.mak
perl util\mk1mf.pl dll nasm debug VC-WIN32 >ms\ntdll.mak
perl util\mk1mf.pl nasm BC-NT >ms\bcb.mak

perl util\mkdef.pl 32 libeay > ms\libeay32.def
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def

就是将第二行和第三行编译选项增加了 debug。修改完成后执行 ms/do_nasm.bat

ms\do_nasm.bat

运行后结果如下:

修改完成执行如下命令开始编译(如果想编译成 dll,则执行 nmake -f ms\ntdll.mak,编译前要修改 ms\ntdll.mak 将 CFLAG 的 /MD 属性修改为 /MT,与你调用项目匹配):

nmake -f ms\nt.mak

如果没有错误,几分钟后编译后的文件就会生成于 D:\openssl-1.0.2p\out32 目录下。

处理文件路径信息是经常要用到的字符串处理的手段,应用场景非常的多,不论是 Linux 还是 Windows,在我没接触这一系列函数之前,都是使用一系列字符串处理函数来自己写。而在 Windows 环境下,系统给我们提供了一系列处理路径相关的 API,我们在需要使用的时候直接调用即可,不但可以避免自己使用字符串处理函数处理时可能造成的各种问题,还可以加快我们编程的速度。当然如果你还没有使用字符串处理函数自己处理过路径等信息,我强烈建议你先自己尝试学习一下。轮子可不重复制造,但你必须要清楚轮子的制作工艺,否则在出现故障时就不知道如何处理了。

继续阅读

用过 VS2012 以上版本的人心里肯定清楚,想通过 Help Viewer 去下载帮助文档,那速度简直无法忍受,选择几个项目一晚上甚至几天都下载不完。很多人被逼的直接用 Google 在线的帮助了,搜索一下函数名结果就直接到 MSDN 的页面中。但并不是所有时候都有网络的,所以最终希望还是要寄托在 Help Viewer 上,但是这货下载速度的确太慢了,为了解决这个问题本文提供两种方案。一种是使用网络上其他人下载好的离线包直接安装(比较大),另外一种就是用一个 CodePlex 上提供的下载工具 Visual Studio 2012/2013/2015 Help Downloader 进行下载。

继续阅读

在日常开发过程中,我们常常用如下这种形式的结构体来传递数据。

typedef struct  _PATH_INFO {
    HANDLE  hPPid;              // 父进程 PID
    HANDLE  hPid;               // 子进程 PID
    ULONG   PathLength;         // 子进程路径长度
    TCHAR   Path[1];            // 用于存储子进程路径
} PATH_INFO, *PPATH_INFO;

其中前三个成员用来描述一个进程的父进程PID和自身进程的PID以及路径长度信息,而最后一个成员来描述该路径的实际内容,由于路径长度是不定的,我们为了节省内存,加了一个 PathLength 的成员来描述路径长度,不会将实际储存路径的成员设置成固定的 512 大小或者 1024 大小,这样会非常浪费内存,在使用过程中,我们会想如下这种方式来给结构体分配内存和填充数据。

继续阅读