Exemplo de HandleRef
Este exemplo demonstra como impedir a coleta de lixo em um objeto gerenciado antes que a função não gerenciada é concluída.Ele também demonstra como usar a função sobrecarga para passar um nulo referência (Nada no Visual Basic) em vez de uma referência a um tipo de valor.
O exemplo HandleRef utiliza a seguinte função não gerenciada, mostrada com sua declaração de função original:
ReadFile exportados de Kernel32.dll.
BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
A estrutura original passada para a função contém os seguintes elementos:
typedef struct _OVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED;
Neste exemplo, a Overlapped estrutura e o Overlapped2 a classe contém IntPtr tipos em vez de tipos ponteiro e o ALÇA tipo.The StructLayoutAttribute atributo é definido para garantir que os membros são organizados em memória seqüencialmente, na ordem em que aparecem.
The LibWrap classe contém protótipos gerenciado para o ReadFile e ReadFile2 métodos. ReadFile passa o Overlapped estrutura sistema autônomo um dos parâmetros. Pela sobrecarga o ReadFile método, a amostra pode passar uma referência nula (Nada no Visual Basic) em vez de uma referência para a estrutura, quando necessário.Nem translation from VPE for Csharp Visual Basic 2005 permitir a passagem um nulo referência ()Nada) diretamente.
ReadFile2 passa o Overlapped2 classe. Por padrão, classes, que são tipos de referência, são passados sistema autônomo in parâmetros.Aplicando o InAttribute e OutAttribute atributos para sistema autônomo causas de declaração Overlapped2 para ser empacotado sistema autônomo um in/out parâmetro. O exemplo pode passar uma referência nula (Nada) diretamente, quando necessário, em vez de uma classe, como classes são tipos de referência e você pode passar uma referência nula (Nada) em seu lugar.The App classe cria uma HandleRef wrapper para o FileStream Para evitar a coleta de lixo ocorra antes de chamadas para ReadFile ou ReadFile2 estão completas.
O código-fonte para os exemplos de código a seguir é fornecido pelo.NET estrutura Invocação de plataforma Tecnologia Exemplo.
Declaração de protótipos
' Declares a managed structure for the unmanaged structure.
< StructLayout( LayoutKind.Sequential )> _
Public Structure Overlapped
…
End Structure 'Overlapped
' Declares a managed class for the unmanaged structure.
< StructLayout( LayoutKind.Sequential )> _
Public Class Overlapped2
…
End Class 'Overlapped2
Public Class LibWrap
' Declares a managed prototypes for unmanaged functions.
' Because Overlapped is a structure, you cannot pass Nothing as a
' parameter. Instead, declares an overloaded method.
Overloads Declare Ansi 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
Overloads Declare Ansi Function ReadFile Lib "Kernel32.dll" ( _
ByVal hndRef As HandleRef, _
ByVal buffer As StringBuilder, _
ByVal numberOfBytesToRead As Integer, _
ByRef numberOfBytesRead As Integer, _
' Declares an int instead of a structure reference.
ByVal flag As IntPtr ) As Boolean
' Because Overlapped2 is a class, you can pass Nothing as a parameter.
' No overloading is needed.
Declare Ansi 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
// Declares a managed structure for the unmanaged structure.
[ StructLayout( LayoutKind.Sequential )]
public struct Overlapped
{
…
}
// Declares a managed class for the unmanaged structure.
[ StructLayout( LayoutKind.Sequential )]
public class Overlapped2
{
…
}
public class LibWrap
{
// Declares managed prototypes for unmanaged functions.
// Because Overlapped is a structure, you cannot pass null as a
// parameter. Instead, declares an overloaded method.
[ DllImport( "Kernel32.dll" )]
public static extern bool ReadFile(
HandleRef hndRef,
StringBuilder buffer,
int numberOfBytesToRead,
out int numberOfBytesRead,
ref Overlapped flag );
[ DllImport( "Kernel32.dll" )]
public static extern bool ReadFile(
HandleRef hndRef,
StringBuilder buffer,
int numberOfBytesToRead,
out int numberOfBytesRead,
IntPtr flag ); // Declares an int instead of a structure reference.
// Because Overlapped2 is a class, you can pass null as parameter.
// No overloading is needed.
[ DllImport( "Kernel32.dll", EntryPoint="ReadFile" )]
public static extern bool ReadFile2(
HandleRef hndRef,
StringBuilder buffer,
int numberOfBytesToRead,
out int numberOfBytesRead,
Overlapped2 flag );
}
Chamando funções
Public Class App
Public Shared Sub Main()
Dim fs As New FileStream( "HandleRef.txt", FileMode.Open )
' Wraps the FileStream handle in HandleRef to prevent it
' from being garbage collected before the call ends.
Dim hr As New HandleRef( fs, fs.Handle )
Dim buffer As New StringBuilder( 5 )
Dim read As Integer = 0
' Platform invoke holds the reference to HandleRef until the 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 'Main
End Class 'App
public class App
{
public static void Main()
{
FileStream fs = new FileStream( "HandleRef.txt", FileMode.Open );
// Wraps the FileStream handle in HandleRef to prevent it
// from being garbage collected before the call ends.
HandleRef hr = new HandleRef( fs, fs.Handle );
StringBuilder buffer = new StringBuilder( 5 );
int read = 0;
// Platform invoke holds a reference to HandleRef until the call
// ends.
LibWrap.ReadFile( hr, buffer, 5, out read, 0 );
Console.WriteLine( "Read with struct parameter: {0}", buffer );
LibWrap.ReadFile2( hr, buffer, 5, out read, null );
Console.WriteLine( "Read with class parameter: {0}", buffer );
}
}
Consulte também
Conceitos
Diversos exemplos de marshaling