6.2.2 类方法与事件函数
KMDF中的事件函数,分开来说:驱动对象有EvtDriverDeviceAdd和EvtDriverUnload,我们将实现前者;设备对象有一系列PNP/Power事件;还有其他对象的事件函数,且忽略之,详见代码。
事件函数说到底是一种回调函数。类普通成员函数,由于编译后会增加this参数,所以无法成为回调函数。只能使用类静态函数,并通过静态函数再回调成员函数。这是一种很通用的实现手段。以EvtDriverDeviceAdd事件函数为例,我们要在类中为它定义两个相关函数。
- Class DrvClass
- {
- // 定义类静态函数,它是全局的,可以作为回调函数
- static NTSTATUS PnpAdd_sta(
- IN WDFDRIVER Driver,
- IN PWDFDEVICE_INIT DeviceInit);
-
- // 再定义类成员函数,将由静态函数内部调用
- virtual NTSTATUS PnpAdd(
- IN WDFDRIVER Driver,
- IN PWDFDEVICE_INIT DeviceInit,
- DrvClass* pThis);
-
- // 其他接口函数
- // ……
- }
要能够通过静态函数回调成员函数,即通过PnpAdd_sta回调PnpAdd函数。前提是要能够获得对象指针,因为我们已经把对象指针保存在驱动对象的环境块中了,所以达到此目的不是难事。代码如下:
- NTSTATUS DrvClass::PnpAdd_sta(IN WDFDRIVER Driver,
- IN PWDFDEVICE_INIT DeviceInit)
- {
- // 取得环境块
- PDRIVEDR_CONTEXT pContext = GetDriverContext(Driver);
-
- // 环境块中存有对象指针
- DrvClass* pThis = (DrvClass*)pContext->par1;
-
- // 再调用成员函数
- return pThis->PnpAdd(Driver, DeviceInit);
- }
所有其他的事件函数,都必须采用相同的方法实现。