Win32 API编程——前言

一丶什么是Win32 API?

  简单来说,就是微软为了保护操作系统的安全性和稳定性,不允许运行在用户层的进程随意操控系统内核,而是必须按照一定方式。我们用户层要与系统内核层交互(比如对内存、进程操作),只能通过调用Windows内核层提供的接口函数,也就是Win32API来操控。这些API以DLL(动态链接库)的形式保存(在SYSTEM32文件夹中,你可以发现许多DLL文件),最常用的是kernel32.dll、user32.dll和gdi32.dll

  所有基于NT内核(XP到Win10都是基于NT内核开发)的Windows API都可以称为Win32,即便是64位系统,也用这个名称,因为64位系统是完全兼容32位程序的(32位系统不能完全兼容16位程序),所以你可以看到这些DLL名称都有个"32"的后缀。那我们用C/C++写程序,没用到Win32,怎么也能够执行分配内存,打开进程等操作呢?实际上在Windows系统上的C/C++的运行库内部也是封装了Win32API。进一步说,所有运行在Windows用户层的程序必须得调用Win32API

  Windows采用分层结构,大致来说就是(用户层->内核层->硬件抽象层->硬件层),每一层使用下一层提供的接口来与下一层进行交互。我们日常使用的应用程序都是运行在用户层,通过调用内核层提供的接口(Win32API)来与内核层交互,然后系统会请求中断(调用nt*.dll函数),调用内核中的中断服务程序,进而对硬件抽象层进行操作,从而实现用户到硬件的交互。当然,也有许多程序是运行在内核层的(比如驱动程序),Windows没有公布用于内核层编程的源码,但是提供了WDK(Windows Driver Kit)来给程序员编写驱动程序,驱动程序可通过内核API,编写中断服务例程来操控硬件抽象层。  

二丶为什么要学Win32 API?  

  现在用于windows平台的编程工具/语言日新月异,种类繁多,比如使用Dephi、WPF、Qt等,开发效率远高于使用Win32 API开发,那为什么还要学习使用Win32 API开发呢?

  ①理解Windows程序底层运行机制。

  ②了解Windows上各种语言、平台的实现原理。

  ③实现其他库没有提供的高级功能,比如修改其他进程内存等。

三丶开始前你必须知道

语言基础: C/C++

开发平台: Visual Studio

编码格式:Unicode

----------------------

为什么区分编码格式?

  windows程序的编码格式分为两种:ANSI(MBCS:多字节字符集)和Unicode,Windows会按程序的编码格式解码字符。

  ANSI:根据系统当前设置的语言采用不同编码,比如系统语言设置为简体中文,则ANSI采用GBK编码。

  Unicode:统一的字符集,在所有系统中均相同,每个字符占用两个字节。

为什么使用Unicode?

  ①Windows NT是使用Unicode开发的,调用API时要把ANSI字符转换成Unicode字符,直接使用Unicode可以提高运行效率。

  ②使你的程序在不同语言的系统上运行时不会出现乱码。

  ③一些API只能处理Unicode字符。

怎么设置Unicode?

修改编译器设置

  项目->属性->高级->字符集:使用Unicode字符集

设置后观察

  项目->属性->C/C++->命令行:看到两个选项 /D "_UNICODE" /D "UNICODE",说明已成功设置为Unicode编码,否则看到选项 /D "_MBCS",说明使用的是MBCS编码。

  其中_UNICODE定义在C运行库的头文件中,UNICODE定义在Windows的头文件中。

----------------------

尽量使用Windows数据类型

  在平时使用C/C++编程时,我们都使用C/C++标准库提供的数据类型,比如:char,shot,int,long int等等,但是在使用Windows API编程时,我们应该尽量使用Windows提供的数据类型,因为Win32 API函数都是使用Windows数据类型编写的,所以你必须要认识它。事实上,这些Windows数据类型都是在windows头文件中对C/C++库原生类型的宏定义,本质上并无差别。下面列举常见的Windows数据类型。

  类型前缀:

  c=const 常量

  u=unsigned 无符号

  p=pointer 指针

  h=handle 句柄

  w=word 字

  dw=double word 双字
  sz=strinszg terminated with a zero 以0结尾的字符串

   lp=long pointer 长指针

  函数后缀:

  A=ansi字符 参数接受ANSI字符

  W=wide宽字符 参数接受Unicode字符

  EX=expand 扩展版函数,在原函数基础上增加某些新的特性

  Windows类型举例:

  typedef int INT;

  typedef int BOOL;

  typedef unsigned int UINT;

  typedef unsigned short WORD;

  typedef WORD near *PWORD;

  typedef WORD far *LPWORD; 

  其他定义详见
  near指针NP,far指针FP,long指针LP,是为了兼容16位程序,在32位编程中都为P(32位指针)

------------------------

在字符串前添加 L标志:该字符串将按宽字符(Unicode)编码

  TEXT、__TEXT(winnt.h内定义的宏)

  如果 UNICODE被定义,则在字符串前添加L

  _T、__T、_TEXT(tchar.h内定义的宏)

  如果 _UNICODE被定义,则在字符串前添加L

#ifdef  UNICODE
  #define __TEXT(x) L##x
#else
  #define __TEXT(x) x
#endif

------------------------

带T前缀的数据类型,根据是否定义UNICODE使用宽/窄字符

#ifdef  UNICODE
    typedef wchar_t TCHAR
#else
    typedef char TCHAR
#endif

 

 

四丶其他

  笔者学习中,尽量在保持准确性、严谨性的同时使用比较自然的语言来写。

  水平有限,不足之处欢迎批评指正。

  

 

 

  本文由Celng原创,转载请标明出处。

 

你可能感兴趣的:(Win32 API编程——前言)