HandleRef Structure
Wraps a managed object holding a handle to a resource that is passed to unmanaged code using platform invoke.
Assembly: mscorlib (in mscorlib.dll)
The HandleRef type exposes the following members.
| Name | Description | |
|---|---|---|
![]() | Equals | Indicates whether this instance and a specified object are equal. (Inherited from ValueType.) |
![]() | Finalize | Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.) |
![]() | GetHashCode | Returns the hash code for this instance. (Inherited from ValueType.) |
![]() | GetType | Gets the Type of the current instance. (Inherited from Object.) |
![]() | MemberwiseClone | Creates a shallow copy of the current Object. (Inherited from Object.) |
![]() ![]() | ToIntPtr | Returns the internal integer representation of a HandleRef object. |
![]() | ToString | Returns the fully qualified type name of this instance. (Inherited from ValueType.) |
| Name | Description | |
|---|---|---|
![]() ![]() | Narrowing(HandleRef to IntPtr) | Returns the handle to a resource of the specified HandleRef object. |
If you use platform invoke to call a managed object, and the object is not referenced elsewhere after the platform invoke call, it is possible for the garbage collector to finalize the managed object. This action releases the resource and invalidates the handle, causing the platform invoke call to fail. Wrapping a handle with HandleRef guarantees that the managed object is not garbage collected until the platform invoke call completes. For a description of platform invoke services, see Consuming Unmanaged DLL Functions.
The HandleRef value type, like GCHandle, is a special type recognized by the interop marshaler. A normal, nonpinned GCHandle also prevents untimely garbage collection, yet HandleRef provides better performance. Although using HandleRef to keep an object alive for the duration of a platform invoke call is preferred, you can also use the GC.KeepAlive method for the same purpose.
The HandleRef constructor takes two parameters: an Object representing the wrapper, and an IntPtr representing the unmanaged handle. The interop marshaler passes only the handle to unmanaged code, and guarantees that the wrapper (passed as the first parameter to the constructor of the HandleRef) remains alive for the duration of the call.
The following example shows how to use HandleRef to keep alive an object passed as the first parameter. The interop marshaler passes only the handle to unmanaged code.
' HandleRef.vb Imports System Imports System.IO Imports System.Text Imports System.Runtime.InteropServices Imports System.Security.Permissions 'typedef struct _OVERLAPPED { ' ULONG_PTR Internal; ' ULONG_PTR InternalHigh; ' DWORD Offset; ' DWORD OffsetHigh; ' HANDLE hEvent; '} OVERLAPPED; ' declared as structure <StructLayout(LayoutKind.Sequential)> _ Public Structure Overlapped Private intrnal As IntPtr Private internalHigh As IntPtr Private offset As Integer Private offsetHigh As Integer Private hEvent As IntPtr End Structure 'Overlapped ' declared as class <StructLayout(LayoutKind.Sequential)> _ Public Class Overlapped2 Private intrnal As IntPtr Private internalHigh As IntPtr Private offset As Integer Private offsetHigh As Integer Private hEvent As IntPtr End Class 'Overlapped2 Public Class LibWrap ' to prevent FileStream to be GC-ed before call ends, ' its handle should be wrapped in HandleRef ' BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, ' LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped); Overloads Declare Unicode Function ReadFile Lib "Kernel32.dll" ( _ ByVal hndRef As HandleRef, _ ByVal buffer As StringBuilder, _ ByVal numberOfBytesToRead As Integer, _ ByRef numberOfBytesRead As Integer, _ ByRef flag As Overlapped) _ As Boolean ' since Overlapped is struct, Nothing can't be passed instead, ' we must declare overload method if we will use this Overloads Declare Unicode Function ReadFile Lib "Kernel32.dll" ( _ ByVal hndRef As HandleRef, _ ByVal buffer As StringBuilder, _ ByVal numberOfBytesToRead As Integer, _ ByRef numberOfBytesRead As Integer, _ ByVal flag As Integer) _ As Boolean ' int instead of structure reference ' since Overlapped2 is class, we can pass Nothing as parameter ' no overload is needed Declare Unicode Function ReadFile2 Lib "Kernel32.dll" Alias "ReadFile" ( _ ByVal hndRef As HandleRef, _ ByVal buffer As StringBuilder, _ ByVal numberOfBytesToRead As Integer, _ ByRef numberOfBytesRead As Integer, _ <[In](), Out()> ByVal flag As Overlapped2) _ As Boolean End Class 'LibWrap Public Class App Public Shared Sub Main() Run() End Sub 'Main <SecurityPermissionAttribute(SecurityAction.Demand, Flags:=SecurityPermissionFlag.UnmanagedCode)> _ Public Shared Sub Run() Dim fs As New FileStream("HandleRef.txt", FileMode.Open) Dim hr As New HandleRef(fs, fs.SafeFileHandle.DangerousGetHandle()) Dim buffer As New StringBuilder(5) Dim read As Integer = 0 ' platform invoke will hold reference to HandleRef until call ends LibWrap.ReadFile(hr, buffer, 5, read, 0) Console.WriteLine("Read with struct parameter: {0}", buffer) LibWrap.ReadFile2(hr, buffer, 5, read, Nothing) Console.WriteLine("Read with class parameter: {0}", buffer) End Sub 'Run End Class 'App
Windows 7, Windows Vista SP1 or later, Windows XP SP3, Windows XP SP2 x64 Edition, Windows Server 2008 (Server Core not supported), Windows Server 2008 R2 (Server Core supported with SP1 or later), Windows Server 2003 SP2
The .NET Framework does not support all versions of every platform. For a list of the supported versions, see .NET Framework System Requirements.




