1、ascii字符串和宽字符串
在驱动程序开发中,ddk将char和wchar_t类别,替换成char和wchar类别驱动程序中用kdprint打印ascii字符串和宽字符串:
打印ascii字符串
char *string = “hello”;
kdprint(“%s\n”, string);
打印宽字符串
wchar *string = l“hello”;
kdprint(“%s\n”, string);
2、ansi_string字符串与unicode_string字符串
2.1、ansi_string字符串:
typedef struct _string
{
ushort length;
ushort maximumlength;
pchar buffer;
}string;
typedef string ansi_string;
typedef pstring pansi_string;
typedef string oem_string;
typedef pstring poem_string;
这个数据结构对ascii字符串进行了封装
length:字符的长度
maximumlength:整个字符串缓冲区的最大长度
buffer:缓冲区的指针
注意:和标准的字符不同,string字符串不是以0标志字符的结束。字符长度依靠length字段。在标准c中的字符串中,如果缓冲区长度是n,那么只能容纳n-1个字符的字符串,这是因为要留一个字节存储null。而在string字符串中,缓冲区的大小maximumlength,最大的字符串长度可以是maximumlength,而不是maximumlength-1
2.2、unicode_string字符串:
typedef struct _unicode_string
{
ushort length;
ushort maxmumlength;
pwstr buffer;
} unicode_string;
length:字符的长度,单位是字节。如果是n个字符,那么length等于n的2倍
maximumlength:整个字符串缓冲区的最大长度,单位也是字节
buffer:缓冲区的指针
2.3、kdprint打印ansi_string字符串与unicode_string字符串
打印ansi_string字符串:
ansi_string ansistring;
//省去对ansistring初始化
kdprint(“%z\n”, &ansistring);
打印unicode_string字符串:
unicode_string unistring;
//省去对unistring初始化
kdprint(“%wz\n”, &unistring);
3、字符串的初始化与销毁
3.1、方法一使用ddk提供了相应的函数
/************************************************************************
* 函数名称:rtlinitansistring
* 功能描述:初始化ansi_string字符串
* 参数列表:
destinationstring:要初始化的ansi_string字符
sourcestring:字符串的内容
* 返回 值:void
*************************************************************************/
void rtlinitansistring(
in out pansi_string destinationstring,
in pcsz sourcestring)
使用方法:
ansi_string ansistring1;
char* string1 = “hello”;
rtlinitansistring(&ansistring1,string1);
/************************************************************************
* 函数名称:rtlinitunicodestring
* 功能描述:初始化unicode_string字符串
* 参数列表:
destinationstring:要初始化的unicode_string字符
sourcestring:字符串的内容
* 返回 值:void
*************************************************************************/
void rtlinitunicodestring(
in out pansi_string destinationstring,
in pcsz sourcestring)
使用方法:
unicode_string unistring1;
char* string1 = “hello”;
rtlinitunicodestring(&unistring1,string1);
这中办法是将ansistring1中的buffer等于string1指针。这种初始化的优点是操作简单,用完后不用清理内存。但带来另外一个问题,如果修改string1,同时会导致ansistring1字符串发生变化
ansi_string ansistring1;
char* string1 = “hello”;
//初始化ansi_string字符串
rtlinitansistring(&ansistring1,string1);
kdprint((“ansistring1:%z\n”, &ansistring1));//打印hello
//改变string1
string1[0]=‘h’;
string1[1]=‘e’;
string1[2]=‘l’;
string1[3]=‘l’;
string1[4]=‘o’;
//改变string1,ansistring1同样会导致变化
kdprint((“ansistring1:%z\n”, &ansistring1));//打印hello
3.2、另外一种方法是程序员自己申请内存,并初始化内存,当不用字符串时
需要回收字符串占用的内存
#define buffer_size 1024
unicode_string unicodestring1 = {0};
//设置缓冲区大小
unicodestring1.maximumlength = buffer_size;
//分配内存
unicodestring1.buffer = (pwstr)exallocatepool(pagedpool, buffer_size);
wchar* widestring = l“hello”;
//设置字符串长度,因为是宽字符,所以是字符长度的2倍
unicodestring1.length = 2 * wcslen(widestring);
//保证缓冲区足够大,否则程序终止
assert(unicodestring1.maximumlength 》= unicodestring1.length);
//内存赋值
rtlcopymemory(unicodestring1.buffer, widestring, unicodestring1.length);
kdprint((“unicodestring:%wz\n”, &unicodestring1));
//清理内存
exfreepool(unicodestring1.buffer);
unicodestring1.buffer = null;
unicodestring1.length = unicodestring1.maximumlength = 0;
清理内存,ddk同样给出了简化函数分别是
rtlfreeansistring
rtlfreeunicodestring
这两个函数内部调用了exfreepool去回收内存
4、字符串复制
/************************************************************************
* 函数名称:rtlcopystring
* 功能描述:ansi_string字符串复制
* 参数列表:
destinationstring:目的字符串
sourcestring:源字符串
* 返回 值:void
*************************************************************************/
void rtlcopystring(
in out pstring destinationstring,
in pstring sourcestring optional);
/************************************************************************
* 函数名称:rtlcopyunicodestring
* 功能描述:unicode_string字符串复制
* 参数列表:
destinationstring:目的字符串
sourcestring:源字符串
* 返回 值:void
*************************************************************************/
void rtlcopyunicodestring(
in out punicode_string destinationstring,
in punicode_string sourcestring optional);
使用方法:
//初始化unicodestring1
unicode_string unicodestring1;
rtlinitunicodestring(&unicodestring1, l“hello world”);
//初始化unicodestring2
unicode_string unicodestring2 = {0};
unicodestring2.buffer = (pwstr)exallocatepool(pagedpool, buffer_size);
unicodestring2.maximumlength = buffer_size;
//将初始化unicodestring1复制到unicodestring2
rtlcopyunicodestring(&unicodestring2, &unicodestring1);
//分别显示unicodestring1和unicodestring2
kdprint((“unicodestring1%wz\n”, &unicodestring1));
kdprint((“unicodestring2%wz\n”, &unicodestring2));
//销毁unicodestring2
//注意unicodestring1不用销毁
rtlfreeunicodestring(&unicodestring2);
5、字符串比较
/************************************************************************
* 函数名称:rtlcomparestring
* 功能描述:ansi_string字符串比较
* 参数列表:
string1:要比较的第一个字符串
string2:要比较的第二个字符串
caseinsensitive:是否对大小写敏感
* 返回 值:比较结果
如果函数返回值为0,表示两个字符串相等
如果小于0,则表示第一个字符串小于第二个字符串
如果大于0,则表示第一个字符串大于第二个字符串
*************************************************************************/
long rtlcomparestring(
in pstring string1,
in pstring string2,
in boolean caseinsensitive);
/************************************************************************
* 函数名称:rtlcompareunicodestring
* 功能描述:unicode_string字符串比较
* 参数列表:
string1:要比较的第一个字符串
string2:要比较的第二个字符串
caseinsensitive:是否对大小写敏感
* 返回 值:比较结果
如果函数返回值为0,表示两个字符串相等
如果小于0,则表示第一个字符串小于第二个字符串
如果大于0,则表示第一个字符串大于第二个字符串
*************************************************************************/
long rtlcompareunicodestring(
in punicode_string string1,
in punicode_string string2,
in boolean caseinsensitive);
如何使用rtlcompareunicoodestring函数
unicode_string unicodestring2;
rtlinitunicodestring(&unicodestring2, l“hello”);
//判断字符串是否相等
if(rtlequalunicodestring(&unicodestring1, &unicodestring2, true))
{
kdprint((“unicodestring1 and unicodestring2 are equal\n”));
}
else
{
kdprint((“unicodestring1 and unicodestring2 are not equal\n”));
}
6、字符串转化成大写
/************************************************************************
* 函数名称:rtlupperstring
* 功能描述:unicode_string字符串转化成大写
* 参数列表:
destinationstring:目的字符串
sourcestring:源字符串
* 返回 值:void
*************************************************************************/
void rtlupperstring(
in out pstring destinationstring,
in pstring sourcestring);
/************************************************************************
* 函数名称:rtlupperstring
* 功能描述:unicode_string字符串转化成大写
* 参数列表:
destinationstring:目的字符串
sourcestring:源字符串
allocatedesttinationstring:是否为目的字符串分配内存
* 返回 值:void
*************************************************************************/
ntstatus rtlupcaseunicodestring(
in out punicode_string destinationstring optional,
in pcunicode_string sourcestring,
in boolean allocatedesttinationstring);
如何使用rtlupcaseunicodestring函数
//初始化unicodestring1
unicode_string unicodestring1;
rtlinitunicodestring(&unicodestring1, l“hello world”);
//变化钱
kdprint((“unicodestring1:%wz\n”, &unicodestring1));
//转换成大写
rtlupcaseunicodestring(&unicodestring1,&unicodestring2,false);
//变化后
kdprint((“unicodestring1:%wz\n”, &unicodestring1));
7、字符串与整型数字相互转换
/************************************************************************
* 函数名称:rtlunicodestringtointeger
* 功能描述:unicode_string字符串转化成整型数字
* 参数列表:
string:需要转化的字符串
base:转换的数的进制(2,8,10,16)
value:需要转换的数字
* 返回 值:指明是否转换成功
*************************************************************************/
ntstatus rtlunicodestringtointeger(
in punicode_string string,
in ulong base optional,
out pulong value);
/************************************************************************
* 函数名称:rtlintegertounicodestring
* 功能描述:unicode_string字符串转化成整型数字
* 参数列表:
value:需要转化的数字
base:转换的数的进制(2,8,10,16)
string:需要转换的字符串
* 返回 值:指明是否转换成功
*************************************************************************/
ntstatus rtlintegertounicodestring(
in ulong value,
in ulong base optional,
out punicode_string string);
字符串与整型数字相互转换的实例
//(1)字符串转换成数字
//初始化unicodestring1
unicode_string unicodestring1;
rtlinitunicodestring(&unicodestring1, l“-100”);
ulong lnumber;
ntstatus nstatus = rtlunicodestringtointeger(&unicodestring1, 10, &lnumber);
if( nt_success(nstatus) )
{
kdprint((“conver to integer successfullu!\n”));
kdprint((“result:%d\n”, lnumber));
}
else
{
kdprint((“conver to integer unsuccessfully!\n”));
}
//(2)数字转换成字符串
//初始化unicodestring2
unicode_string unicodestring2;
unicodestring2.buffer = (pwstr)exallocatepool(pagedpool, buffer_size);
unicodestring2.maximumlength = buffer_size;
nstatus = rtlintegertounicodestring(200, 10, &unicodestring2);
if( nt_success(nstatus) )
{
kdprint((“conver to string successfuall!\n”));
kdprint((“result:%wz\n”, &unicodestring2));
}
else
{
kdprint((“conver to string unsuccessfully!\n”));
}
//注销uniocdestring2
//注意:unicodestring1不用销毁
rtlfreeunicodestring(&uniocdestring2);
8、ansi_string字符串与unicode_string字符串相互转换
/************************************************************************
* 函数名称:rtlunicodestringtoansistring
* 功能描述:将unicode_string字符串转化成ansi_string字符串
* 参数列表:
destinationstring:需要转化的字符串
sourcestring:需要转换的原字符串
allocatedesctinationstring:是否需要对被转换的字符串分配内存
* 返回 值:指明是否转换成功
*************************************************************************/
ntstatus rtlunicodestringtoansistring(
int out pansi_string destinationstring,
in punicode_string sourcestring,
in boolean allocatedesctinationstring);
/************************************************************************
* 函数名称:rtlansistringtounicodestring
* 功能描述:将ansi_string字符串转化成unicode_string字符串
* 参数列表:
destinationstring:需要转化的字符串
sourcestring:需要转换的原字符串
allocatedesctinationstring:是否需要对被转换的字符串分配内存
* 返回 值:指明是否转换成功
*************************************************************************/
ntstatus rtlansistringtounicodestring(
int out punicode_string destinationstring,
in pansi_string sourcestring,
in boolean allocatedesctinationstring);
ansi_string字符串与unicode_string字符串的相互转换
//(1)将unicode_string字符串转换成ansi_string字符串
//初始化unicodestring1
unicode_string unicodestring1;
rtlinitunicodestring(&unicodestring1, l“hello world”);
ansi_string ansistring1;
ntstatus nstatus = rtlunicodestringtoansistring(&ansistring1, &unicodestring1, true);
if( nt_success(nstatus) )
{
kdprint((“conver successfully!\n”));
kdprint((“result:%z\n”, &ansistring1));
}
else
{
kdprint((“conver unsuccessfully\n”));
}
//销毁ansistring1
rtlfreeansistring(&ansistring1);
//(2)将ansi_strin字符串转换成gunicode_string字符串
//初始化ansistring2
ansi_string ansistring2;
rtlinitstring(&ansistring2, “hello world”);
unicode_string unicodestring2;
nstatus = rtlansistringtounicodestring(&unicodestring2, &ansistring2, true);
if( nt_success(nstatus) )
{
kdprint((“conver successfully!\n”));
kdprint((“result:%z\n”, &unicodestring2));
}
else
{
kdprint((“conver unsuccessfully\n”));
}
//销毁unicodestring2
rtlfreeunicodestring(&unicodestring2);
台湾5G频谱竞标金额已达1216.21亿元,但还未决胜负
Magic Leap 2定于2021年发布 将有5G技术更宽的视野及更小更轻的外形
如何区分DV数码摄像机行货与水货
原位掺杂、扩散和离子注入的相关原理及其区别介绍
如何理解区块链中的派发和增发
Windows内核模式下的字符串操作
音响中的阻抗
热烈庆祝地凯公司正式通过CRCC铁路产品认证
近期苹果申请了两项新的专利
五菱征途盲订24小时收获订单837台
iphone14pro什么时候上市 价格还香不香
Versal ACAP、APU - DSB 指令后可能会发生推测性 TLB 填充
如何避免聊天机器人的5个错误策略
AT&T和纬创NeWeb Corp.开发了M14A2A Cat-1和M18Q2F Cat-4模块
升特发布4D Touch系列产品SX8654/55/56/57/58
GTC23 | 美敦力与 NVIDIA 携手打造医疗设备 AI 平台
用于降低共模噪声的12 位ADC LTC2309
面板双虎抢占Micro LED市场!
编程sector0中的page0时候总是失败问题
淡化线上渠道,能否为苹果带来更多的增量?