API核心DLL与Unicode和多字节
前面几章基本都是总体的叙述与了解过程,所以挑重点记录以下笔记
2.3 Windows核心DLL
动态链接库文件DLL:
包括了Windows API 函数可执行程序。
DLL时将各函数“导出” API 函数主要存在于几个核心的动态连接库文件中.
Kenid32.dll 是最重要的 DLL,Windows 系统最主要的系统服务 API 函数都存在于 Kernel32.dll 中。
User32.dll 主要包括图形用户界面中所使用到的一些函数接口。
GDI32.dll中,主要包括 Windows 图形引擎中的接口函数。
在应用程序调用一个 API 前, 操作系统会通过程序文件(exe) 中的导入表结构找到需要调用的API函数位于哪个DLL,并确定函数在内存中的地址, 应用程序才可以成功调用 API 函数。
2.3.1 核心DLL简介
DLL | 简介 |
---|---|
Kernel32.dll | Kernel32.dll 包括了系统基本服务中最基本的 API 函数,如文件系统、进程与线程、内存管理等。 |
User32.dll | Uscr32.dll是Windows 图形用户界面的主要支持。 一些重要的图形用户界面函数由 User32.dll函数导出。 |
Gdi32.dll | Gdi32.dll 是 Windows GDI 应用程序设计接口,Gdi32.dll 导出了与此相关的若干函数, 如GetTextColor、 LineTO、 TextOut等。 |
标准 C 函数及 CrtdIl_dll | 任何支持 C 语言应用程序开发的操作系统都应该提供 C 语言库函数的调用。正是由于各个主流操作系统都提供了一套标准 C 库所定义的函数接口, 标准 C 函数库才会有如此广泛的跨越操作系统平台,Windows 系统的 C 标准库函数接口主要由 CrtdIl_dll 导出。 |
其他 Dll | Windows 系统中的 DLL 文件远远不止这几个, Windows 系统提供了非常丰富而且功能强大的 API, 上文介绍了 Windows API 所主要依赖的几个 DLL。 |
2.4 Unicode和多字节
Windows 既可以使用 Unicode 字符集又可以使用传统的字符集( 如多字节编码) 来实现对多种语言的支持, 以适应国际市场的要求。
Unicode 是世界通用的字符编码标准, 使用 16 位数据表示一个字符, 一共可以表示 65535 种字符, 可以包括现代计算机中所使用的所有字符, 包括各种字母、 文字、 在出版业中使用的特殊符号等。
传统的字符集, 如 Windows ASNI 字符集, 使用 8 位数据或将相邻的两个 8 位的数据组合在一起表示特殊的语言字符。 Windows 系统采用了 ASNI 字符的扩展方式, 如果一个字节是负数, 则将其后续的一个字节组合在一起表示一个字符。 这种编码方式的字符集也称作“ 多宇节” 字符集。
书上的代码实例,不同宽度字符串的初始化,并将字符串的输出进行比较,这里提以下,用.c文件源代码不会出现错误和警告。代码如下:
#include<Windows.h>
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR iCmdLine, _In_ int nCmdShow)
{
//定义LPWSTR类型的字符串
LPWSTR szUnicode = L"This is aUnicode String";
//定义LPSTR类型的窄字符串
LPSTR szMutliByte = "This is not a Unicode String";
//定义LPTSTR类型的自适用字符串
LPTSTR szString = TEXT("This string is Unicode or not depends on the option.");
//使用W版本的API函数,以宽字符串为参数
MessageBoxW(NULL, szUnicode, L"字符编码1", MB_OK);
//使用 A 版本的 API 函数, 以窄字符串为参数
MessageBoxA(NULL, szMutliByte, "字符编码2", MB_OK);
//根据编译条件自动选择 A 版本或 W 版本的 API 函数, 采用相适应的字符串类型为参数
MessageBox(NULL, szString, TEXT("字符编码3"), MB_OK);
return 0;
}
三种字符串变量的初始化方式:
类型:变量类型 | 初始化方式 |
---|---|
Unicode:LPWSTR | L"string" |
多字节:LPSTR | “string” |
根据开发环境的设置自动适应:LPTSTR | TEXT(“string”) |
书本中为我们以二进制的方式进行了对比这里我自己理解了下,如果有错,请指出:
这里内存是以ASNI的方式显示,所以Unicode是乱码
很明显可以看出Unicode的宽字符是以2个字节显示,ASNI是以1个字节显示,
这里如果把内存显示改为Unicode,如下:
与上图内存中对比,可以看出MessageBox的标题也以中文的方式显示出来了,回到书中:
在工程配置中设置编码的方式:
“配置属性” —>“常规”—>“字符集” 选项中进选择。
2.4.1 W版本和A版本的API
先看图:
Windows 系统 API 凡是以字符串作为参数的很多具有 W 和 A 两个版本以实现两种不同编码的字符处理。
在 User32.dll 中导出的函数实际上没有 MessageBox, 只有 MessageBoxA 和 MessageBoxW, 这两者是同一个 API, 实现了同样的功能。 不同的是, MessageBoxA 以多字节字符串作为参数输入,MessateBoxW 以 Unicode 字符串作为参数输入。
在程序进行编译和连接时, 如果程序在 UNICODE 环境下, 会使用 MessageBoxW,否则使用 MessageBoxA。
2.4.2 Unicode与ASCII的转换
Windows 专门提供了若干个 API 来实现对字符编码的转换工作, WideCbarToMuItiByte,MultiByteToWideChar,UnicodeToBytes 函数可以完成这些工作。
WideCharToMuJtiByte 函数将 Unicode 字符串转换为多字节字符串, 以适应 A 版本的 API,MultiByteToWideChar 函数将多字节字符串转换为了 Unicode 字符串, 以适应 W 版本的 API 的参数形式耍求。