




免费预览已结束,剩余1页可下载查看
下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
很少有专题讲内核中的C+编程,中文资料恐怕更是罕见。由于C+的普及性、与C的亲密关系,以及大部分情况下程序员都使用C+编译器编译C程序的事实,当初学者听说内核中“不容易”(笔者也听说过“无法”二字)用C+进行编程时,会大吃一惊。不管是说者无意,还是听者有心,Windows内核的现状,决定了C语言是内核编程的首选。其实内核驱动中也能使用C+,也能使用类,但和用户程序中的用法有一些区别,一些特殊的地方需要特别注意。从笔者的经验来看,WDK给出的AVStream小端口驱动示例工程,就都是C+代码,这是由于AVStream的模块性非常强,在实现较大功能模块时,非得用类封装,否则难以表述清楚。本章专门讲述如何在内核中编写C+驱动程序。笔者先写一个简单的例子,显示类的一些基本特性,并由此交代出几项关键点;然后改造WDF USB设备驱动开发一章中的WDFCY001驱动的例子,将它全部改造成一个驱动类,并最终实现C+的最大优点:多态。6.1.1 一个简单的例子首先我们尝试把用户程序中最简单的类拷贝到内核中,编译链接,看看行不行。下面就是笔者定义的整数类,它封装一个整数,对象能够被当成整数使用。1. classclsInt 2. Public: 3. clsInt()m_nValue=0; 4. clsInt(intnValue)m_nValue=nValue; 5. voidprint()KdPrint(“m_nValue:%d ”,m_nValue); 6. operatorint()returnm_nValue; 7. 8. private: 9. intm_nValue; 10. ; 上例是一个非常简单的类定义,我们将在DriverEntry函数中使用它,分别定义一个局部变量和动态创建一个对象。我们通过Debug信息来观察对象行踪,希望能够得到正确的输出。入口函数中的定义如下:1. externCNTSTATUSDriverEntry( 2. INPDRIVER_OBJECTDriverObject, 3. INPUNICODE_STRINGRegistryPath 4. ) 5. 6. /创建两个对象,一个是局部变量,一个是动态创建的 7. clsIntobj1(1); 8. clsInt*obj2=new(NonPagedPool,abcd)clsInt(2); 9. 10. /打印Log信息 11. obj1.print(); 12. obj2-print(); 13. deleteobj2; 14. 15. /让模块加载失败 16. returnSTATUS_UNSUCCESSFUL; 17. 上面代码中先后创建了两个clsInt对象,一个是在栈中创建的,初始变量为1;一个是动态创建的,初始变量为2。后者由于是动态创建的,必须手动调用delete函数释放内存,所以其析构函数比前者先调用。我们必须从Log信息中得到类似的脉络,以证明其正确性。代码请参看simClass工程。图6-1是Log信息的截图,我们如愿以偿地得到了想要的结果。图6-1 对象Log信息6.1.2 new/delete查看上面的代码,会发现一个不同于以往的new操作符。这是怎么回事呢?我们这一节就讲讲它。在用户程序中,创建和释放一个对象使用 new/delete方法,其底层乃是调用HeapAllocate/HeapFree 堆API从线程堆栈中申请空间。但问题是,内核CRT没有提供new/delete操作符,所以需要自己定义。自定义的new/delete操作符,自然也是能够从堆栈中分配内存的,内核中有RtlAllocateHeap/RtlFreeHeap堆栈服务函数。但在内核中,我们一般使用内存池来获取内存,实际上内存池和堆栈使用了同一套实现机制。使用ExAllocatePool/ExFreePool函数对从内存池申请/释放内存,下面是一个例子。1. _forceinline 2. void*_cdecloperatornew(size_tsize, 3. POOL_TYPEpool_type, 4. ULONGpool_tag) 5. 6. ASSERT(pool_typeMaxPoolType)&(0!=size); 7. if(size=0)returnNULL; 8. 9. /中断级检查。分发级别和以上的级别只能分配非分页内存 10. ASSERT(pool_type=NonPagedPool| 11. (KeGetCurrentIrql()DISPATCH_LEVEL); 12. 13. returnExAllocatePoolWithTag(pool_type, 14. static_cast(size), 15. pool_tag); 16. 上面的函数定义有几个细节的地方应当注意一下。首先注意new操作符重载,它的第一个参数一定是size_t,用来表示将分配缓冲区的长度;其次注意分页内存和非分页内存的区别,即pool_type所表示者,在DISPATCH_LEVEL及以上的级别是不能分配分页内存的。下面是使用new进行内存申请的一个例子。1. /定义一个32位的TAG值 2. #defineTAGabcd 3. /外部已经定义了一个clsName类 4. externclassclsName; 5. 6. /为clsName申请对象空间 7. clsName*objName=NULL; 8. objName=new(NonPagedPool,TAG)clsName(); 上面的new操作和用户程序中的new操作具有同样的功效,但需要注意第一个参数size_t是必须外置的,编译器会自动用sizeof(clsName)求取长度并作为第一个参数。一般地说,对于类似下面的语句:className objName = new() className()其执行过程是,首先由new操作符为新对象动态分配内存,并返回指针;然后再对此新创建的对象,选择与className() 相符的构造函数进行初始化。再来看看delete操作符的重载。1. _forceinline 2. void_cdecloperatordelete(void*pointer) 3. 4. ASSERT(NULL!=pointer); 5. if(NULL!=pointer) 6. ExFreePool(pointer); 7. 删除对象数组,即delete操作符重载。1. _forceinline 2. void_cdecloperatordelete(void*pointer) 3. 4. ASSERT(NULL!=pointer); 5. if(NULL!=pointer) 6. ExFreePool(pointer); 7. 上面两个函数最终都会将指定地址的内存释放,但在释放之前,前者会调用指定对象的析构函数,后者会对数组中每个成员调用析构函数。示例如下:1. externclsName*objName; 2. externclsName*objArray; 3. deleteobjName; 4. deleteobjArray; 6.1.3 extern C对extern C编译指令,大家不会感到陌生。它一般这样用:1. externC 2. /内容 3. 既然是编译指令,就一定是作用于编译时刻的。它告诉编译器,对于作用范围内的代码,以C编译器方式编译。一般是针对C+/Java等程序而用的。如果括号内仅有一项,那么括号可以省略。最早让我们见识到它的作用的是在入口函数DriverEntry中。现在必须这样声明它:1. externCNTSTATUSDriverEntry( 2. INPDRIVER_OBJECTDriverObject, 3. INPUNICODE_STRINGRegistryPath 4. ); 初学者未必知道这一点,如果“忘记”做上述改动,将得到如下错误:error LNK2019: unresolved external symbol _DriverEntry8 referenced in function _GsDriverEntry8error LNK1120: 1 unresolved externals很奇怪,这是一个链接错误,说明编译过程是通过的。怎么回事呢?认真看一下错误内容,原来是系统在链接时找不到入口函数_DriverEntry8。这个奇怪的函数名,很显然是C编译器对DriverEntry进行编译后的结果,前缀“_”是C编译器特有的,后缀“8”是所有参数的长度。原来我们现在使用的是
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 象棋知识培训通知课件
- 2025版全屋定制家居产品进出口合同
- 2025版冷链物流设备采购与安装服务合同范本
- 2025年户外家具定制及全国市场销售合同
- 2025版城市综合体物业运营管理服务合同书
- 2025版路灯照明设备定期检修维护服务合同
- 2025版商品房预售协议合同示范文本执行指南
- 2025便利店夜间营业安全保障承包协议
- 2025年度高科技企业知识产权转让合同范本
- 2025年房屋抵押贷款到期续贷合同范本
- 审理室业务课件培训
- 2025年四川省辅警招聘考试题库及答案
- 预防出生缺陷健康讲座
- 2025吐鲁番辅警考试真题
- 船舶建造全流程解析
- 幼儿园膳食儿童过敏防护会议记录范文
- 2025至2030中国航空客运销售代理行业市场运行发展分析及前景趋势与投资报告
- 肾功能衰竭患者的麻醉管理要点
- 不等齿宽永磁同步电动机电磁力波特性与振动抑制策略研究
- 首诊负责制试题及答案
- 2024浙江遂昌农商银行新员工招聘笔试历年典型考题及考点剖析附带答案详解
评论
0/150
提交评论