オブジェクトの有効期間の管理
警告
UMDF 2 は UMDF の最新バージョンであり、UMDF 1 に取って代わるものです。 すべての新しい UMDF ドライバーは、UMDF 2 を使用して記述する必要があります。 UMDF 1 には新機能が追加されておらず、Windows 10 の新しいバージョンでは UMDF 1 のサポートが制限されています。 ユニバーサル Windows ドライバーでは、UMDF 2 を使用する必要があります。
アーカイブされた UMDF 1 サンプルは、Windows 11, バージョン 22H2 - 2022 年 5 月 ドライバー サンプル アップデートでご確認いただけます。
詳しくは、UMDFの概要をご覧ください。
UMDF は参照カウント スキームを使用して、コールバック オブジェクト と フレームワーク オブジェクトの有効期間を管理します。
ドライバーによって提供されるコールバック オブジェクトへの参照の管理
ほとんどの場合、ドライバーはコールバック オブジェクトへの参照を保持する必要はありません。 コールバック オブジェクト インターフェイスのメソッドが、フレームワークにと、有効期間がコールバック オブジェクトとコールバック オブジェクトのペアフレームワーク オブジェクトに依存するオブジェクトによってのみ呼び出される場合、ドライバーは参照を保持する必要はありません。 つまり、ドライバーまたはフレームワークは、オブジェクト階層の上位にあるオブジェクト インターフェイスのメソッドを安全に呼び出すことができます。
フレームワーク オブジェクトへの参照の管理
UMDF では、一般的な COM 有効期間の原則と WDF 固有の有効期間モデルによって、フレームワーク オブジェクトの有効期間が決まります。 フレームワーク オブジェクトが適切なタイミングでメモリから解放されるように、ドライバーは両方のモデルの基準を満たす必要があります。
COM有効期間管理
COM では、通常、呼び出し元はオブジェクトの使用中にオブジェクトへの参照を保持し、そして、呼び出し元はオブジェクトが不要になったときに参照を解放します。 ただし、UMDF ドライバーは、フレームワーク オブジェクトへの参照を保持する必要はありません。 実際、ドライバーは、ドライバーがフレームワーク オブジェクトを作成した直後にフレームワーク オブジェクト参照を解放できます。
たとえば、UMDF サンプルは、IWDFDriver::CreateDeviceを呼び出した後にデバイス オブジェクトを解放します。 参照は早期に解放されますが、WDF オブジェクト ツリーが参照を保持するため、デバイス オブジェクトはデバイスが取り外されるまで存在し続けます。
UMDF はオブジェクト ツリー内のすべてのフレームワーク オブジェクトを追跡するため、ドライバーはフレームワーク オブジェクトへの参照を保持する必要はありません。
ただし、ドライバーがフレームワーク オブジェクトへの参照を保持している場合、ドライバーは、オブジェクトが不要になったときに参照を解放する必要があります。 循環参照はドライバーがその参照を解放するまで所定の位置に残ります。 循環参照を回避するために、ドライバーは通常、フレームワーク オブジェクトへの明示的な参照を保持すべきではありません。
ドライバーがフレームワーク オブジェクトへの参照を保持する必要がある場合は、ドライバーのコールバック オブジェクトもIObjectCleanupインターフェイスを実装する必要があります。 ドライバーがフレームワーク オブジェクトで IWDFObject::DeleteWdfObjectを呼び出すと、フレームワーク オブジェクトは対応するコールバック オブジェクトのIObjectCleanup::OnCleanupメソッドを呼び出します。 IObjectCleanup::OnCleanupの実装では、フレームワークがフレームワーク オブジェクトの破棄を完了できるように、フレームワーク オブジェクトへの参照を解放する必要があります。
WDF 有効期間管理
デフォルトの親をオーバーライドできるタイプのオブジェクトを作成する場合は、オブジェクトの有効期間に一致する有効期間を持つ親を選択する必要があります。 デフォルトの親オブジェクトの詳細と、ドライバーがデフォルトの親をオーバーライドできるかどうかについては、Framework Objectsの表をご参照ください。
オブジェクトの有効期間が一致している場合、フレームワークは親オブジェクトが削除されたときにオブジェクトを削除します。 オブジェクトの有効期間が一致せず、デフォルトの親が削除される前にオブジェクトを削除したい場合は、オブジェクトが不要になったときに DeleteWdfObjectを呼び出すことによってオブジェクトを明示的に削除できます。
たとえば、新しいリクエストオブジェクトを作成し、IWDFDriver::CreateWdfMemoryを呼び出してこのリクエストのメモリ オブジェクトを作成する場合、リクエストオブジェクトを新しいメモリ オブジェクトの親として指定できます。 WDF は親オブジェクトが削除されたときに子オブジェクトを削除するため、ドライバーはDeleteWdfObjectを呼び出してメモリ オブジェクトを削除する必要はありません。
ただし、有効期間がオブジェクトの有効期間とほぼ一致する親がなく、デフォルトの親が削除される前にオブジェクトを削除したい場合は、明示的な削除を使用する必要があります。 たとえば、ドライバーは、短い期間に使用される複数のリクエストオブジェクトを作成できます。 この場合、ドライバーは、不要になったリクエストを明示的に削除することによってメモリを節約することができます。
同様に、デフォルトの親をオーバーライドできないオブジェクトを作成し、デフォルトの親が削除される前にオブジェクトを削除したい場合、ドライバーはオブジェクトを明示的に削除する必要があります。