Exemplo de OpenFileDlg
Este exemplo demonstra como chamar uma função não gerenciada que espera um ponteiro para uma estrutura que contém uma seqüência de caracteres.Além disso, ele demonstra como usar um gerenciado classe para representar um un gerenciado estruturar como aplicar o InAttribute e OutAttribute atributos para a classe de realizar marshaling de volta para o chamador e como declarar e inicializar campos diferentes da classe para produzir un correto gerenciado representação.
O exemplo OpenFileDlg utiliza a seguinte função não gerenciada, mostrada com sua declaração de função original:
GetOpenFileName exportados de Comdlg32.dll.
BOOL GetOpenFileName(LPOPENFILENAME lpofn);
The LPOPENFILENAME a estrutura do API do Win32, que é passado para a função anterior, contém os seguintes elementos:
typedef struct tagOFN {
DWORD lStructSize;
//…
LPCTSTR lpstrFilter;
//…
LPTSTR lpstrFile;
DWORD nMaxFile;
LPTSTR lpstrFileTitle;
DWORD nMaxFileTitle;
LPCTSTR lpstrInitialDir;
LPCTSTR lpstrTitle;
//…
LPCTSTR lpstrDefExt;
//…
} OPENFILENAME, *LPOPENFILENAME;
Neste exemplo, a OpenFileName classe contém sistema autônomo elementos da estrutura original sistema autônomo membros de classe. Estrutura não gerenciada é declarada sistema autônomo uma classe, em vez de sistema autônomo uma estrutura gerenciada para mostrar sistema autônomo uma classe pode ser usada quando a função não gerenciada espera um ponteiro para uma estrutura.Como uma classe gerenciada é um tipo de referência, quando ele é passado por valor, um ponteiro para a classe é passado para código não gerenciado.Isso é exatamente o que espera a função não gerenciada.
The StructLayoutAttribute atributo é aplicado à classe para garantir que os membros são dispostos em memória seqüencialmente, na ordem em que aparecem. The Conjunto de caracteres campo é definido para invocação de plataforma que pode escolher entre ANSI e Unicode formatos em time de execução, com base em plataforma de destino.
The LibWrap classe contém o protótipo do gerenciado de GetOpenFileName método, que passa a OpenFileName classe sistema autônomo um parâmetro de entrada/saída. Aplicando InAttribute and OutAttribute explicitamente, o exemplo garante que OpenFileName é empacotado sistema autônomo um parâmetro de entrada/saída e o chamador podem ver sistema autônomo alterações novamente empacotadas. (Para desempenho, o padrão de atributo direcional para uma classe é, que impede que o chamador vendo as alterações empacotadas novamente.) The App classe cria uma nova instância das OpenFileName classe e usa o Marshal.SizeOf método para determinar o dimensionar em bytes, da estrutura não gerenciada.
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
' Declare a class member for each structure element.
< StructLayout( LayoutKind.Sequential, CharSet:=CharSet.Auto )> _
Public Class OpenFileName
Public structSize As Integer = 0
'…
Public filter As String = Nothing
'…
Public file As String = Nothing
Public maxFile As Integer = 0
Public fileTitle As String = Nothing
Public maxFileTitle As Integer = 0
Public initialDir As String = Nothing
Public title As String = Nothing
'…
Public defExt As String = Nothing
'…
End Class 'OpenFileName
Public Class LibWrap
' Declare managed prototype for the unmanaged function.
Declare Auto Function GetOpenFileName Lib "Comdlg32.dll" ( _
<[In], Out> ByVal ofn As OpenFileName ) As Boolean
End Class 'LibWrap
// Declare a class member for each structure element.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Auto )]
public class OpenFileName
{
public int structSize = 0;
//…
public String filter = null;
//…
public String file = null;
public int maxFile = 0;
public String fileTitle = null;
public int maxFileTitle = 0;
public String initialDir = null;
public String title = null;
//…
public String defExt = null;
//…
}
public class LibWrap
{
// Declare a managed prototype for the unmanaged function.
[ DllImport( "Comdlg32.dll", CharSet=CharSet.Auto )]
public static extern bool GetOpenFileName([ In, Out ]
OpenFileName ofn );
}
Chamando funções
Public Class App
Public Shared Sub Main()
Dim ofn As New OpenFileName()
ofn.structSize = Marshal.SizeOf( ofn )
ofn.filter = "Log files" & ChrW(0) & "*.log" & ChrW(0) & _
"Batch files" & ChrW(0) & "*.bat" & ChrW(0)
ofn.file = New String( New Char( 256 ) {})
ofn.maxFile = ofn.file.Length
ofn.fileTitle = New String( New Char( 64 ) {})
ofn.maxFileTitle = ofn.fileTitle.Length
ofn.initialDir = "C:\"
ofn.title = "Open file called using platform invoke..."
ofn.defExt = "txt"
If LibWrap.GetOpenFileName( ofn ) Then
Console.WriteLine( "Selected file with full path: {0}", _
ofn.file )
End If
End Sub 'Main
End Class 'OpenFileDlgSample
public class App
{
public static void Main()
{
OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf( ofn );
ofn.filter = "Log files\0*.log\0Batch files\0*.bat\0";
ofn.file = new String( new char[ 256 ]);
ofn.maxFile = ofn.file.Length;
ofn.fileTitle = new String( new char[ 64 ]);
ofn.maxFileTitle = ofn.fileTitle.Length;
ofn.initialDir = "C:\\";
ofn.title = "Open file called using platform invoke...";
ofn.defExt = "txt";
if( LibWrap.GetOpenFileName( ofn ))
{
Console.WriteLine( "Selected file with full path: {0}",
ofn.file );
}
}
}
Consulte também
Tarefas
Invocação de plataforma Tecnologia Exemplo
Conceitos
Tipos de dados de invocação de plataforma