Exemplo de buffers
Este exemplo mostra como transmitir seqüências como In/Out parâmetros para funções não gerenciadas que esperam uma seqüência de caracteres (LPSTR) como um parâmetro de função. Além disso, ele mostra como usar uma seqüência de caracteres retornada de um método não gerenciado no caso especial onde o chamador não deve para liberar a memória alocada para a seqüência de caracteres.
Essa plataforma de amostra chama duas funções nativas do Win32 exportadas do Kernel32. dll:
GetSystemDirectory
Recupera o caminho do diretório do sistema.
GetCommandLine
Recupera a seqüência de linha de comando para o processo atual.
O LibWrap classe contém um gerenciado protótipos para as funções não gerenciadas, que são chamados de Main no aplicativo de console. O CharSet campo será definido para essa plataforma chamar pode escolher entre ANSI e Unicode formatos em tempo de execução, com base na plataforma de destino. Para obter mais informações sobre esse campo, consulte Especificando um conjunto de caracteres.
O GetSystemDirectory o método de protótipo substitui uma StringBuilder buffer para o não gerenciado LPSTR tipo. O tamanho do buffer permanece fixo. Para acomodar os requisitos da função original, GetSystemDirectory passa a variável de tamanho de buffer como o segundo argumento. A StringBuilder de buffer, em vez de uma seqüência de caracteres, substitui o LPTSTR tipo na declaração. Ao contrário de cadeias de caracteres, que são imutáveis, StringBuilder buffers podem ser alterados.
O nativo GetCommandLine função retorna um ponteiro para um buffer alocado e de propriedade do sistema operacional. Quando o empacotamento de strings como tipos de retorno, o empacotador de interoperabilidade pressupõe que ele deve liberar a memória que o original LPTSTR tipo apontada pela função. Para impedir que o empacotador automaticamente recuperar essa memória, o gerenciado GetCommandLine prototype retorna um IntPtr tipo em vez de uma seqüência de caracteres. O PtrToStringAuto método copia o não gerenciado LPSTR tipo de um objeto string gerenciada, ampliando o formato de caractere, se necessário.
A declaração de protótipos
Public Class LibWrap
Declare Auto Sub GetSystemDirectory Lib "Kernel32.dll" _
(ByVal sysDirBuffer As StringBuilder, ByVal buffSize As Integer)
Declare Auto Function GetCommandLine Lib "Kernel32.dll" () As IntPtr
End Class
public class LibWrap
{
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern int GetSystemDirectory(StringBuilder
sysDirBuffer, int size);
[DllImport("Kernel32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr GetCommandLine();
}
public ref class LibWrap
{
public:
[DllImport("Kernel32.dll", CharSet=CharSet::Auto)]
static int GetSystemDirectory(StringBuilder^
sysDirBuffer, int size);
[DllImport("Kernel32.dll", CharSet=CharSet::Auto)]
static IntPtr GetCommandLine();
};
Chamando funções
Public Class App
Public Shared Sub Main()
' Call GetSystemDirectory.
Dim sysDirBuffer As New StringBuilder(256)
LibWrap.GetSystemDirectory(sysDirBuffer, sysDirBuffer.Capacity)
' ...
' Call GetCommandLine.
Dim cmdLineStr As IntPtr = LibWrap.GetCommandLine()
Dim commandLine As String = Marshal.PtrToStringAuto(cmdLineStr)
End Sub
End Class
public class App
{
public static void Main()
{
// Call GetSystemDirectory.
StringBuilder sysDirBuffer = new StringBuilder(256);
LibWrap.GetSystemDirectory(sysDirBuffer, sysDirBuffer.Capacity);
// ...
// Call GetCommandLine.
IntPtr cmdLineStr = LibWrap.GetCommandLine();
string commandLine = Marshal.PtrToStringAuto(cmdLineStr);
}
}
public ref class App
{
public:
static void Main()
{
// Call GetSystemDirectory.
StringBuilder^ sysDirBuffer = gcnew StringBuilder(256);
LibWrap::GetSystemDirectory(sysDirBuffer, sysDirBuffer->Capacity);
// ...
// Call GetCommandLine.
IntPtr cmdLineStr = LibWrap::GetCommandLine();
String^ commandLine = Marshal::PtrToStringAuto(cmdLineStr);
}
};
Consulte também
Conceitos
Tipos de dados de invocação de plataforma
Padrão de empacotamento de Strings
Outros recursos
Creating Prototypes in Managed Code