MapPtrToProccess()、GetCallerProccess() 应用程序与驱动程序的数据传递
扫描二维码
随时随地手机看文章
在Win CE5.0驱动程序中:
MapPtrToProccess()函数允许将一个指针从一个地址空间映射到另一个地址空间,通过调用该函数,用于获得对应用程序空间数据的访问。
GetCallerProccess()函数则用于获取调用进程的句柄。
他们的用法如下:
pReadBuffer=MapPtrToProccess(pBuffer,GetCallerProccess());
*pReadBuffer=g_Temp; //返回函数
其中pReadBuffer是驱动程序中一个函数的实参变量,用来保存转换后的指针,pBuffer是这个函数的形参,对应于调用这个函数的应用程序的实参,而g_Temp 变量则是驱动程序的一个全局变量。应用程序调用驱动程序的这个函数来取得驱动的全局变量,但是驱动程序和应用程序的加载地址空间不是一个,他们两个的指针是不能通用的,应该转换,这两个函数的作用就是这个,第一行转换指针空间,使pReadBuffer指针指向应用程序的实参,这样的话,往pReadBuffer里面写入数据(即第二行代码),应用程序就会通过调用驱动中的这个函数来得到传回的全局变量的值,达到读取驱动中全局变量的目的。
另外插一段付林林老师的经典语录,以供参考:
驱动程序和应用程序之间传递数据时何时调用MapPtrToProcess?
因为设备管理器负责加载驱动程序DLL,这意味着当应用程序调用驱动程序接口函数的时候,WINCE内核会将调用驱动程序接口函数的线程转移到设备管理器的进程空间然后执行具体的驱动程序代码,应用程序和设备管理器处于两个进程空间,这就造成设备管理器无法访问应用程序传递的指针(虚拟地址),所以当我们在应用程序中传递指针给流驱动程序接口函数时,WINCE内核从中作了一个地址映射,例如ReadFile、WriteFile、DeviceIoControl函数的参数凡是指针都经过了映射才传递给驱动程序,所以很多驱动程序开发者并不了解其中的奥秘就可以编程了。但是如果参数是一个指向一个结构体的指针,而结构体里包括一个或多个指针,那么WINCE内核并不负责映射,所以就需要开发者在驱动程序接口函数中调用API函数MapPtrToProcess来映射地址。例如:pPointer_retval = MapPtrToProcess(pPointer, GetCallerProcess());
我起初读到这篇文章时如获至宝,读完一编之后便欣然尝试,结果试了N个小时,居然不灵,还以为是自己对结构体操作错误,但当我再次细致的阅读此语录后,赫然发现我的理解有误,他老人家说的是结构体中的每一个指针成员都要转换映射,而我理解的却是把传过来的结构体指针变量映射,结果是该映的我没映,不该映的让我映的一塌糊涂,悲哉!哀哉!
最后总结一句话,大意、马虎猛于(真)虎也!!!