




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第一章 驱动的准备1. 驱动程序完成以下功能:Ø 对设备初始化和释放;Ø 把数据从内核传送到硬件和从硬件读取数据;Ø 读取应用程序传送给设备文件的数据和回送应用程序请求的数据;Ø 检测和处理设备出现的错误。2. 整个硬件系统资源在驱动程序面前是赤裸裸的,驱动可以使用所有系统资源,编写驱动程序时我们必须格外小心驱动代码的边界条件,确保它们不会损坏整个操作系统。3. WinCE毕竟是一个嵌入式系统,有其自身的特殊性,为了提高运行效率,所有驱动皆为动态链接库,驱动实现中可以调用所有标准的API。而在其他Windows系统中可能的驱动文件还有.vxd,.sys和
2、动态链接库。4. Windows支持的驱动: 1)虚拟设备驱动程序(Virtual Device Driver):Windows3.1(Windows95/98/Me) 2)内核模式驱动程序(Kernel Mode Driver):Windows NT 3)Win32驱动程序模型(Win32 Driver Mode):从Windows98开始使用。其中WDM是目前主流,然而在WinCE系统中,由于硬件资源有限和嵌入式系统的特点,对其的支持非常有限。第二章 WINCE驱动1.WINCE驱动模型目前Windows CE提供了4种设备模型,其中2种专门用于Windows CE 模型,另外2种模型来自
3、于其它的操系统,如图1所示:基于Windows CE的驱动模型外部驱动模型流接口驱动程序本机驱动程序NDIS驱动程序USB驱动程序设备管理器GWES 系统引导时间设备加载时间应用程序加载时间图1 Windows CE 各种驱动模型的关系2.我们的工作为了帮助开发者快速地开发Windows CE驱动程序,微软在Platform Builder中提供了大量的驱动程序例源代码,同时,芯片厂商或OEM厂商有时也提供一些设备的驱动程序源代码,这些驱动程序源代码在多数情况下可以直接拿来使用,但是在少数情况下需要开发者根据自己的设备硬件特性做一些移植的工作,修改例源代码,重新编译和调试驱动程序。移植工作虽然
4、没有像开发一个全新的驱动程序那样富有挑战性,但它仍具有相当大的难度,其原因如下:移植工作仍然要求开发者具有良好的软、硬件基础,熟悉驱动程序的基本开发和调试方法,并要求具有一定的开发环境和测试手段。移植工作仍然需要了解驱动程序的架构,需要确切知道驱动程序对外暴露哪些接口,微软提供了哪些接口,还必须实现哪些接口等。对于同一设备的驱动程序,其源代码往往位于Platform Builder多个不同的安装目录,移植工作首先需要找出所移植驱动程序的所有源代码的位置。移植工作需要在所移植驱动程序的所有源代码中区分出与硬件有关的代码和独立于硬件的代码,熟悉每个软件模块的大致功能,找出需要更改的与特定硬件有关的
5、代码,并详细分析这些代码。大部分驱动程序的代码放在目录%_WINCEROOT%publicCOMMONoakdrivers下,这些驱动程序都是与平台无关的。此外,对于不同的平台,在BSP目录中也有一些驱动程序的代码,它们在%_WINCEROOT%platform<BSP Name>src drivers中,这些驱动都是与平台相关的。移植工作所修改的源代码有可能仅仅只有几十行甚至几行代码,但在修改之前却需要花费大量的时间了解驱动架构、熟悉驱动接口、分析源程序代码、找出需要修改的位置。本质上讲,移植与从头开发一个驱动的差别仅仅在于少写了很多程序。省去了编写这部分程序的时,但对驱动程序开
6、发者的水平要求似乎并没有丝毫的降低。第三章 流接口函数流接口函数也称作流接口驱动程序的入口点,每个流接口驱动程序必须实现一组标准的函数,用来实现标准的文件I/O函数和电源管理函数,这些函数提供给Windows CE操作系统的内核使用。这些函数通常叫做流接口驱动程序的DLL接口。以下介绍几个主要的流接口驱动接口函数。(1)DWORD XXX_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)参数:DWORD hDeviceContext,设备驱动的句柄,由XXX_ Init函数创建的时候返回。 DWORD AccessCod
7、e,传给驱动程序使用的地址,这个地址跟读和写有关。 DWORD ShareMode,共享模式,这个参数用于一些特殊的设备。例如一些PC卡的设备读或写的时候是否可以共享。返回值:返回驱动程序引用事例句柄。描述:这个函数用于打开一个设备驱动程序,当应用程序准备对某一个设备进行读或写操作时,系统必须先执行CreateFile( )这个函数用于打开这个设备。这个函数执行以后系统才能够执行读和写操作。(2)BOOL XXX _ Close(DWORD hOpenContext)参数:DWORD hOpenCnntext,设备驱动的引用事例句柄,由XXX_Open创建。返回值:调用成功返回TRUE ,失败
8、返回FALSE口描述:这个函数用于关闭一个驱动程序的引用实例。应用程序通过CloseHandle()来调用这个函数,当执行完这个函数的时候驱动程序引用的事例,hOpenContext将不再有效。(3)DWORD XXX_ Init(DWORD dwContext)参数:DWORD dwContext,指向字符串的指针。通常这个参数都为一个流接口驱动在注册表内的设置。返回值:如果调用成功返回一个驱动程序的句柄。描述:当用户开始使用一个设备的时候,例如,当PC卡初始化的时候,设备管理器调用这个函数来初始化PC卡设备。这个函数并不是由应用程序直接调用的,而是通过设备管理器提供的ActivateDev
9、iceEx( )函数来调用的。函数执行后如果成功则返回一个设备的句柄。(4)BDOL XXX_ Deinit(DWORD hDeviceContext)参数:DWORD hDeviceContext,由xxx_ Init创建时生成的设备句柄。返回值:调用成功返回TRUE ,失败返回FALSE。描述:当一个用户需要卸载一个驱动程序的时候,设备管理器调用这个函数来卸载这个驱动程序,应用程序不能够直接调用这个函数,设备管理器通过DeactivateDeviec()函数调用这个函数。(5)DWORD XXX_ Read(DWORD hOpenContext, LPVOID pBuffer, DWORD
10、 Count)参数:DWORD hOpenContext, CreateFile()函数返回的句柄。 LPVOID pBuffer,一个缓冲区地址用于从驱动读数据。 DWORD Count,需要读缓冲区的长度。返回值:实际读取字节的长度。描述:这个函数与ReadFile很相似,当一个流接口驱动程序已经被打开后,应用程序可以使用ReadFile( )函数对这个设备进行读操作,ReadFile()里面的hFile参数就是这个设备的引用实例句柄hOpenContext,而参数lpBuffer将传给pBuffer,用于表示要读/写缓冲区的地址。参数nNumberofBytesToRead将传送给Cou
11、nt,用于表示要读写缓冲区的长度。同样,返回的参数,如果操作成功则返回实际读/写的地址,如果操作失败则返回值为-1。(6)DWORD XXX_Write (DWDRD hOpenContext,LPCVOID puffer,DWDRD Count) 参数:DWDRD hOpenContext,由CreateFile()函数返回的句柄。 LPVOID pBuffer, 一个缓冲区地址,用于从驱动写数据。 DWORD Count,需要写缓冲区的长度。返回值:实际写入字节的长度。描述:当一个流接口驱动程序打开以后,应用程序可以使用WriteFile ()函数进行写操作。(7)BOOL XXX_ IO
12、Control (DWORD hQpenContext. WORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenDut, PDWORD pdwActualOut )参数:DWORD hOpenContext,由CreateFile()函数返回的句柄。 WORD dwCode,特殊的WORD 型用于描述这次IOControl操作的语义,一般这个都由用户自己定义。 PBYTE pBufIn,缓冲区指针指向需要传送给驱动程序使用的数据。 DWORD dwLenIn,要传送给驱动程序使用数据的长度。 PI3YTE pBu
13、fOut,缓冲区指针指向驱动程序传给应用程序使用的数据: DWDRD dwLEnOut,要传送给应用程序使用数据的长度。 PDWORD pdwActualOut,DWORD型指针用于返回实际处理数据的长度。返回值:调用成功返回TRUE,调用失败返回FALSE。 描述:这个函数通常用于向设备发送命令。应用程序使用DeviceIOControl函数来通知操作系统调用这个函数。通过参数dwCode来通知驱动程序要执行的操作。这个函数扩展了流接口驱动程序的功能(8)VOID XXX_ PowerDown (DWORD hDeviceContext)参数:DWORD hDeviceContext,由XX
14、X_ Init创建时生成的设备句柄。返回值:无返回值。(9)VOID XXX_PowerUp ( DWORD hDeviceContext )参数:WORD hDeviceContext,由XXX_ init创建时生成的设备句柄。返回值:无返回值。描述:PowerDown和PowerUp这两个函数通常都必须要硬件的支持才能够有效,也是说相关的硬件必须支持PowerDown和PowerUp这两个模式。(10)VOID XXX_Seek(hDeviceContext, Long Amount, WORD Type)参数:hDeviceContext,由XXX_ init创建时生成的设备句柄。 Lo
15、ng Amount 定义要移动的设备数据的指针的字节数 WORD Type 定义数据指针的起始点返回值:无返回值描述:当一个应用程序调用SetFilePointer函数移动设备数据指针时,操作系统会调用XXX_Seek函数。如果一个设备可以被多次打开,这个函数只修改由hDeviceContext定义的设备实例的数据指针。第四章 最简单的流接口函数对于一个驱动我们要认清楚里面到底有哪些文件,他们的作用又是干什么的呢?下面以 SimpleDriver为例,进行第一个简单流接口驱动的讲解。* 1.Makefile文件这里的Makefile文件请 不要和其他环境下(GCC,VS2005)的Makefi
16、le文件弄混,它是BSP里面的Makefile。Windows CE中的Makefile比较特别,它包含对所有项目都通用的配置信息。其内容很简单,只有一句话:!INCLUDE $(_MAKEENVROOT)makefile.def当build.exe查找dirs和source文件之后,它就会设置一个内部环境变量。这个环境变量可以被Nmake.exe传递给编译器、连接器或其他工具。* 2.source文件source也是一个文本文件,它为子目录中的源代码设置了不少宏定义。 TARGETNAME=SimpleDriverRELEASETYPE=PLATFORMTARGETTYPE=DYN
17、LINKTARGETLIBS=$(_COMMONSDKROOT)lib$(_CPUINDPATH)coredll.lib DEFFILE=$(TARGETNAME).defDLLENTRY=DllEntrySOURCES=SimpleDriver.c以上是simpledriver里面source的内容,具体解释如下:TARGETNAME=SimpleDriver; 指定生成最终生成的.exe,.lib,.dll文件的名称,这里是SimpleDriver.dllRELEASETYPE=PLATFORM; 它设置两种旗标:RELEASEDIR和RELE
18、ASELIBDIR,用于指定编译生成二进制和库文件存放的目录。默认情况下,为目标生成的二进制和库文件存放在目录%_PROJECTROOT%oak下,这里存放在D:WINCE600PLATFORMMini2440targetARMV4Iretail目录下。TARGETTYPE=DYNLINK;这个宏定义指定构建文件的最终类型,可以把TARGETTYPE类型设置为以下四种类型中的任意一种。1)MANAGED_EXE;2) MANAGED_DLL;3) MANAGED_WINEXE;4) MANAGED_MODULE; 这里设置的最终类型为dll。TARGETLIBS=$(_COMMONSDKROO
19、T)lib$(_CPUINDPATH)coredll.lib ;_COMMONSDKROOT等价于WINCE600publiccommonsdk它指定了额外的库文件(.lib)和目标文件(.Obj)链接为目标可执行文件(.exe或.dll).这里将 coredll.lib 链接生成最终的目标文件SimpleDriver.dllDEFFILE=$(TARGETNAME).def; 它指定模块定义文件(.def)的名称,这里指定了模块定义文件的名称为SimpleDriver.defDLLENTRY=DllEntry; 它为一个DLL文件指定DLL的入口函数,此时
20、TARGETTYPE被设置为DYNLINK。如果 DLLENTRY对应的值没有被设置时,那么 DllMainCRTStartUp是DLL的C程序运行入口点。这里 DLLENTRY的入口函数被指定为DllEntry,因而,上面的 TARGETTYPE被设置成DYNLINK;SOURCES=SimpleDriver.c; 它包含编译过程的文件列表,这些列表中包含汇编文件和源文件,这些文件的类型有.cxx,.cpp,.c,.asm,.s,.src,.rc,.obj,.ire,.res,.odl,.tlb,.i,.cs,.resx等。这些文件编译之后可能是静态库文件(.l
21、ib),也有可能是动态库文件(.dll)。这里编译过程中需要用到的源文件有SimpleDriver.c,编译之后的生成SimpleDriver.dll的动态链接库文件。* 3.SimpleDriver.def文件.def文件定义了DLL的导出函数列表。这里包括的内容如下:LIBRARY SimpleDriverEXPORTSSPL_InitSPL_DeinitSPL_OpenSPL_CloseSPL_ReadSPL_WriteSPL_SeekSPL_IOControl SPL_PowerDownSPL_PowerUp主要是针对当前流接口函数,将相应的函数导出。* 4. SimpleDriver
22、.h这个而就不用多介绍了吧,主要是一些头文件的声明,定义等等 * 5.SimpleDriver.c下面给出基本的代码,有些函数给出了空定义,方便以后实现,同时方便理解。* 6. platform.reg配置文件的编写。涉及到的文件有.platform.bib,platform.reg,dirs,source,SimpleDriver.def,其中后面两个文件在前文已有绍,这里就以前两个配置文件为主。首先,从注册表说起,先简单的介绍一下注册表:Makeimg.exe使用.reg文件来 为CE镜像建立注册表并添加默认的键值。也就是说,在.reg中写入的注册表的键值会被默认地放入CE镜像的初始化注册
23、表中。其中Platform.reg定义了目标设备硬件的注册表设置,Project.reg定义基于Windows CE项目工程的注册表设置。注册表键值的类型如下:1. REG_SZ表示一个字符串类型,如reg_sz:”my string”。2. REG_DWORD表示一个双字节类型,如dword:12345678(十六进制数)。3. REG_MULTI_SZ表示多字符串类型,如mul
24、ti_sz:“my string”,“my string”。4. REG_BINARY 二进制类型。在实际应用中可以使用IF/ENDIF关键字来引入一个注册表设置块,通过设置一个环境变量或一个特殊的值来达到这个目的。为了包含一个注册表设置块,当一个环境变量没有被设置或者没有等于一个特定的值的时候,引入的注册表设置块的行尾应使用一个空格和“!”。这里比较好找,一目了然,在目录D:WINCE600PLATFORMSMDKXXXXFilesplatform.reg下添加:HKEY_LOCAL_MACHINEDriversBuil
25、tInSPL "Prefix"="SPL" "Dll"="SimplDriver.Dll" "FriendlyName"="Simple Driver" "Order"=dword:0 /驱动安装顺序 "Index"=dword:0 /驱动名的数字部分注:O
26、rder给所有的驱动设置相对安装顺序。Order 为0的驱动先安装,依次安装Order为1,2,的驱动。Oder可以让开发者保证有相到依赖关系的多个驱动以适当的顺序进行安装。Index指定在文件系统中的驱动名的数字部分。在默认情况下,带有前缀COM的驱动在文件系统中分配名字为 COM1,下一个即为COM2。为了保证驱动总是安装成COM2,必须提供Index = 2。这样在WINCE启动时,就自动加载该驱动了。* 7. platform.bib接着我们介绍platform.bib文件,关于bib文 件,这里做一个简要的介绍:二进制镜像文件构建文件(.bib)定义了哪个模块或者文件被包含到运行时的
27、CE镜像中。在编译期间,makeimg.exe使若干个.bib文 件合并成ce.bib文件,然后,romimage.exe使用ce.bib决 定哪些文件应该被打包进运行时CE镜像中,它同时还使用ce.bib来决定如何加载模块和文件到CE镜像(下载到目标设备的CE镜像)所在的内存中。按照功能划分,.bib文件可以分为如下几种类型。(1) Platform.bib。Platform.bib位于目录D:WINC
28、E600PLATFORMSMDK6410Files,它包含硬件平台相关的模块和文件,如目标设备的驱动文件。这些模块和文件是CE镜像的入口,比如.exe文件,如波形音频文件(.wav)等。(2) Project.bib。Project.bib 位于目录 D:WINCE600PUBLICCEBASEOAKFILES,如果我们新建一个工程项目(OSDesign1)则这个工程位于目录:D:WINCE600OSDe
29、signsOSDesign1OSDesign1Wince600SMDK6410_ARMV4IOAKfiles下。Project.bib文件定义与创建CE镜像的工程相关的模块,如果在OSDesign1中创建了一个自己的模块或者应用程序,那么就要把它们添加到Project.bib文件中的MODILES部分。(3) Common.bib。Common.bib位于目录D:WINCE600PUBLICCOMMONO
30、AKFILES下,它定义了CE镜像文件包含的通用显示驱动和核心系统模块。(4) Config.bib。Config.bib位于目录D:WINCE600PLATFORMSMDK6410Files下,它定义了ROM和RAM的配置信息。它同样包含了CE镜像文件的MEMORY和CONFIG部分。Config.bib的MEMORY部分定义了运行时CE镜像内存分配表,指定了名称、地址、大小和MEMORY区域的类型。.
31、bib文件可以被分为四个部分,分别是MEMORY、CONFIG、MODULES和FILES。下 面将分别说明这四个部分各自的含义。(1) MEMORY。定义可用的物理内存,包括起始地址、大小和内存类型。(2) CONFIG。定义romimage.exe输出的配置选项。默认情况下,这个区域是在config.bib文件中。不过,也并不是.bib文件中必须要包含CONFIG部分。(3)
32、FILES。指定放在CE镜像中的文件列表。(4) MODULES。 指定放在CE镜像 总的模块列表,包括EXE和DLL文件,与FILES的 区别是放在MODULES中的文件通常是代码文件,并且构建系统时不会压缩这些文件。这里我们主要介绍Modules部分。Modules部分指定了哪些基于Windows CE的模块包含到CE镜像中,以及如何给加载到config.bib文件中的MEMORY部 分建立内存表。这个部分可以包含200个模块,这些模块有源代码和数据两个部分组成。MODULES的语法格式如下:;
33、Name Path Memory block Section override Memory Type; - - - - -各参数之间用空格分隔。NAME:这个参数指定了MODULES模块的名称。通常情况下,它就像被路径引用的文件名称一样。PATH:指定要打包进CE镜像的MODULES模块的完整路径。MEMORY BLOCK:这个参数指定romimage.exe加载目标模块到内存区域的ra
34、mimage(镜像)部分。这个内存位于config.bib文件中memory 部分指定的某一段内存。SECTION OVERRIDE:这个参数的设置时可选的,它可以为modules、files或者空。如果设置了这个参数,那么构建系统就会根据它来决定这一项是modules还是files。TYPE:这个参数指定文件的类型,主要有以下几种类型,在实际的使用中可以选用其中的一种或者多种组合。1. S:定义一个系统文件2. H:定义一个隐藏文件3. &
35、#160; R:压缩资源,只应用于MODULES部分4. C:如果应用于一个模块,则压缩全部内容5. D:运行时不允许调试。6. N:标记一个模块为不可信任的,只应用MODULES部分。7. K:指定romimage.exe必须修正模块到一个内核地址。在这个过程中
36、,romimage.exe分配一个固定的虚拟地址给DLL,设置了此标志的模块只可以被loadKernelLibrary()函数加载。8. P:指定romimage.exe禁止在头文件中检查指定的CPU类型。这个旗标只用于资源dll,可以在一种CPU伤 编译,在不同CPU上使用。9. M:表示对此页禁止按序调页。10. U:表示不压缩此文件。在目录D:WINCE600PLATFORMSMDKXXXXFilesplatform.bi
37、b文件中有如下定义:; Name Path Memory Type; - &
38、#160;- -;-Simple Driver (caichang714)-simpledriver.dll $(_FLATRELEASEDIR)simpledriver.dll NK SHK; CESYSGEN ENDIF CE_MODULES_DEVICE;-其 中,_$(_FLATRELEASEDIR) 指的是生成的镜像所在目录,即D:
39、WINCE600OSDesignsSMDKXXXXSMDKXXXXRelDir结合上面的说明,我们可以知道,上面的语句的意思是将编译生成的simpledriver.dll模块加载到CE运行时镜像NK中。它的文件属性是系统文件,隐藏文件和内核模块,由romimage.exe分配一个固定的虚拟地址给simpledriver.DLL。接 着在D:WINCE600PLATFORMSMDKXXXXSrcDrivers目录下找到dirs文件,在里面添加:SimpleDriver 最后点击build或者在dos环境下 build -cOK!到这里点击编译就可以了。这个新驱动程序的动态链接库将会被编
40、译进内核。当调用CreateFile()函数(第一个参数是SPL)时就搜索注册表,设备管理器可以找到这个驱动,驱动的入口点可以用到其他程序。第五章 需要注意的事项1.驱动程序的内存访问及函数入口当要在内核模式下执行代码时,必要时需访问整个物理内存空间,这一点与用户模式下执行是截然不同的。因为一个在用户模式运行的IST需要通过访问一个物理内存块来与一个设备进行交互,所以必须要把这个物理内存块映射到IST运行的地址空间。把一个物理内存块映射到执行IST的地址空间有两种方法:VirtualAlloc()申请虚拟内存块和VirtualCopy()绑定物理内存块与虚拟内存块1) 申请一个虚拟内存块LPV
41、OID VirtualAlloc( LPVOID lpAdress, /申请虚拟内存块的起始地址 DWORD dwsize, /申请内存块的大小,以B为单位,不能设为0 DWORD flAllocationType, /申请的类型,分为COMMIT和RESERVE /COMMIT: 在内存或者磁盘上为指定的页面区域分配物理存储 /RESERVE:保留一定范围的IST进程的虚拟地址空间不分配物理存储 DWORD flProtect /访问权限);如果调用成功,返回分配的首地址,调用失败,返回NULL 你可以通过GetLastError函数来获取错误信息。注:VirtualAlloc()函数对虚拟
42、内存块的申请分为两步,首先是执行保留动作,它在此期间做的工作只是在进程的虚拟地址空间内保留一段空间,并没有分配实际的物理内存,保留的虚拟内存并不能被应用程序直接使用。其次,执行提交动作后,这样后才真正的为虚拟内存块映射一段物理内存。执行成功之后,将返回一个内存块指针给用户。2) 一个物理地址块与一个虚拟内存块的绑定BOOL VirtualCopy(LPVOID lpvDest, /绑定目的地址:虚拟内存块LPVOID lpvSrc, /绑定源地址:物理内存块DWORD cbSize, /要绑定的大小DWORD fdwProject /访问权限)返回值:成功返回TRUE,失败返回FALSE注:当
43、虚拟内存所要的工作处理完成,需要调用VirtualFree()函数来释放此虚拟内存。VirtualCopy()函数支持PAGE_PHYSICAL旗标,当映射驻留在512MB之外的物理内 存时,也就是在物理地址大于0x1FFFFFFF时,必须设置此标志。3)释放内存BOOL VirtualFree(LPVOID lpAddress, / 区域地址SIZE_T dwSize, / 区域大小,字节DWORD dwFreeType / 类型);LPVOID lpAddress, 要释放的页的区域的地址,如果dwFreeType指定为MEM_RELEASE且这个区域是被保留的话,那么这个地址就要指定为分
44、配区域的首地址SIZE_T dwSize, 要释放页的大小,如果dwFreeType类型中包含了MEM_RELEASE,则dwSize必须为0DWORD dwFreeType 类型说明MEM_DECOMMIT 消VirtualAlloc提交的页MEM_RELEASE 指定页,如果指定了这个类型,则dwSize应设置为0, 否则函数会调用失败返回值:如果调用成功,返回一个非0值调用失败,返回04)BOOL WINAPI DllEntry(HINSTANCE DllInstance, INT Reason, LPVOID Reserved )这个函数是动态链接库的入口,每个动态链接库都需要输出这个
45、函数,它只在动态库被加载和卸载时被调用,也就是设备管理器调用LoadLibrary而引起它被装入内存和调用UnloadLibrary将其从内存释放时被调用, 因而它是每个动态链接库最早被调用的函数,一般用它做一些全局变量的初始化。参数: DllInstance:DLL的句柄,与一个EXE文件的句柄功能类似,一般可以通过它在得到DLL中的一些资源,例如对话框,除此之外一般没什么用处。 Reason: 一般我们只关心两个值:DLL_PROCESS_ATTACH与DLL_PROCESS_DETACH,Reason等于前者是动态库被加载,等于后者是动态库被释放。所以,我们可以在Reason等于前者是初始化一些资源,等于
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025至2030年中国色织点点布项目投资可行性研究报告
- 手术室护理敏感指标
- 2025至2030年中国果汁市场发展预测及投资策略分析报告
- 2025至2030年中国干燥设备行业发展预测及投资策略报告
- 2025至2030年中国咖啡行业市场运行态势及发展战略研究报告
- 2025至2030年PEPVC塑料管项目投资价值分析报告
- 2025至2030年4-甲基亚硫酸亚乙酯项目投资价值分析报告
- 2025年高渡高臭氧水处理机项目可行性研究报告
- 2025年陶瓷滤料项目可行性研究报告
- 2025年铝壶除垢剂项目可行性研究报告
- 近视眼的防控课件
- 妊娠期的高血压疾病培训课件
- 《数据科学与大数据技术导论》完整版课件(全)
- 抖音直播运营团队薪酬绩效考核管理方案(直播带货团队薪酬绩效提成方案)
- 压电陶瓷精品课件
- 教学课件·植物组织培养
- 部编版语文一年级下册识字8-人之初市级优质课课件
- 基于仿真的轴承动力学分析设计毕业设计说明书
- 丽声北极星分级绘本第二级下Eek,Spider 教学设计
- (高清正版)JJF 1908-2021 双金属温度计校准规范
- 云南省学业水平考试网络管理系统培训
评论
0/150
提交评论