Padrão de marshaling de strings

O System.String e System.Text.StringBuilder classes têm comportamento semelhante de marshaling.

Seqüências de caracteres são empacotadas sistema autônomo um estilo COM BSTR Digite ou sistema autônomo uma matriz de caractere nulo de terminação de referência)Nothing no Visual Basic). sistema autônomo caracteres na seqüência de caracteres podem ser empacotados sistema autônomo Unicode ou ANSI ou de forma dependente de plataforma (Unicode no Microsoft Windows NT, Windows 2000 e Windows XP; ANSI no Windows 98 e Windows Millennium edição (Windows Me).

Este tópico fornece as seguintes informações sobre marshaling de tipos de seqüência de caracteres:

  • Seqüências de caracteres usadas em interfaces

  • Seqüências de caracteres usadas na invocação de plataforma

  • Seqüências de caracteres usadas em estruturas

  • Buffers de string de comprimento fixo

Seqüências de caracteres usadas em interfaces

A tabela a seguir mostra sistema autônomo opções de marshaling para tipo de dados String quando empacotado sistema autônomo um argumento de método para código não gerenciado.The MarshalAsAttribute atributo fornece vários UnmanagedType valores de enumeração para realizar realizar marshaling strings para interfaces COM.

Tipo de enumeração

Descrição do formato não gerenciado

UnmanagedType.BStr (padrão)

Um estilo COM BSTR com um comprimento prefixado e caracteres Unicode.

UnmanagedType.LPStr

Um ponteiro para uma matriz de caracteres ANSI terminada com caractere nulo.

UnmanagedType.LPWStr

Um ponteiro para uma matriz de caracteres Unicode terminada com caractere nulo.

Esta tabela se aplica a cadeias de caracteres.No entanto, para StringBuilder , as únicas opções permitidas são UnmanagedType.LPStr e UnmanagedType.LPWStr.

O exemplo a seguir mostra as seqüências de caracteres declaradas no IStringWorker interface.

public interface IStringWorker {
void PassString1(String s);
void PassString2([MarshalAs(UnmanagedType.BStr)]String s);
void PassString3([MarshalAs(UnmanagedType.LPStr)]String s);
void PassString4([MarshalAs(UnmanagedType.LPWStr)]String s);
void PassStringRef1(ref String s);
void PassStringRef2([MarshalAs(UnmanagedType.BStr)]ref String s);
void PassStringRef3([MarshalAs(UnmanagedType.LPStr)]ref String s);
void PassStringRef4([MarshalAs(UnmanagedType.LPWStr)]ref String s);
);

O exemplo a seguir mostra a interface correspondente, descrita em uma biblioteca de tipos.

[…]
interface IStringWorker : IDispatch {
HRESULT PassString1([in] BSTR s);
HRESULT PassString2([in] BSTR s);
HRESULT PassString3([in] LPStr s);
HRESULT PassString4([in] LPWStr s);
HRESULT PassStringRef1([in, out] BSTR *s);
HRESULT PassStringRef2([in, out] BSTR *s);
HRESULT PassStringRef3([in, out] LPStr *s);
HRESULT PassStringRef4([in, out] LPWStr *s);
);

Seqüências de caracteres usadas na invocação de plataforma

Argumentos de seqüência de caracteres de cópias, converter do formato do .NET estrutura (Unicode) no formato não gerenciado do plataforma invocação de plataforma.Seqüências de caracteres são imutáveis e são copiadas não volta de memória não gerenciada para memória gerenciada quando a telefonar retorna.

A tabela a seguir lista sistema autônomo opções de marshaling de strings quando empacotado sistema autônomo um argumento de método de um invocação de plataforma telefonar.The MarshalAsAttribute atributo fornece vários UnmanagedType valores de enumeração para realizar realizar marshaling strings.

Tipo de enumeração

Descrição do formato não gerenciado

UnmanagedType.AnsiBStr

Um estilo COM BSTR com um comprimento prefixado e caracteres ANSI.

UnmanagedType.BStr

Um estilo COM BSTR com um comprimento prefixado e caracteres Unicode.

UnmanagedType.LPStr

Um ponteiro para uma matriz de caracteres ANSI terminada com caractere nulo.

UnmanagedType.LPTStr (padrão)

Um ponteiro para uma matriz de caracteres dependente de plataforma terminada com caractere nulo.

UnmanagedType.LPWStr

Um ponteiro para uma matriz de caracteres Unicode terminada com caractere nulo.

UnmanagedType.TBStr

Um estilo COM BSTR com um comprimento prefixado e caracteres dependente de plataforma.

VBByRefStr

Um valor que permite que o Visual Basic .NET alterar uma seqüência de caracteres em código não gerenciado e ter que os resultados são refletidos no código gerenciado.Este valor é suportado somente para invocação de plataforma.

Esta tabela se aplica a cadeias de caracteres.No entanto, para StringBuilder , as únicas opções permitidas são LPStr, LPTStr, e LPWStr.

A definição de tipo a seguir mostra o uso correto de MarshalAsAttribute para a plataforma chame chamadas.

Class StringLibAPI    
Public Declare Auto Sub PassLPStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.LPStr)> s As String)    
Public Declare Auto Sub PassLPWStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.LPWStr)> s As String)    
Public Declare Auto Sub PassLPTStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.LPTStr)> s As String)    
Public Declare Auto Sub PassBStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.BStr)> s As String)    
Public Declare Auto Sub PassAnsiBStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.AnsiBStr)> s As String)    
Public Declare Auto Sub PassTBStr Lib "StringLib.Dll" _
(<MarshalAs(UnmanagedType.TBStr)> s As String)
End Class
class StringLibAPI {
[DllImport("StringLib.Dll")]
public static extern void PassLPStr([MarshalAs(UnmanagedType.LPStr)]
String s);
[DllImport("StringLib.Dll")]
public static extern void 
PassLPWStr([MarshalAs(UnmanagedType.LPWStr)]String s);
[DllImport("StringLib.Dll")]
public static extern void 
PassLPTStr([MarshalAs(UnmanagedType.LPTStr)]String s);
[DllImport("StringLib.Dll")]
public static extern void PassBStr([MarshalAs(UnmanagedType.BStr)]
String s);
[DllImport("StringLib.Dll")]
public static extern void 
PassAnsiBStr([MarshalAs(UnmanagedType.AnsiBStr)]String s);
[DllImport("StringLib.Dll")]
public static extern void PassTBStr([MarshalAs(UnmanagedType.TBStr)]
String s);
}

Seqüências de caracteres usadas em estruturas

Seqüências de caracteres são válido membros do estruturas; no entanto, StringBuilder buffers são inválidos em estruturas. A tabela a seguir mostra sistema autônomo opções de marshaling para tipo de dados String quando o tipo é empacotado sistema autônomo um campo.The MarshalAsAttribute atributo fornece vários UnmanagedType valores de enumeração para realizar realizar marshaling strings para um campo.

Tipo de enumeração

Descrição do formato não gerenciado

UnmanagedType.BStr

Um estilo COM BSTR com um comprimento prefixado e caracteres Unicode.

UnmanagedType.LPStr

Um ponteiro para uma matriz de caracteres ANSI terminada com caractere nulo.

UnmanagedType.LPTStr

Um ponteiro para uma matriz de caracteres dependente de plataforma terminada com caractere nulo.

UnmanagedType.LPWStr

Um ponteiro para uma matriz de caracteres Unicode terminada com caractere nulo.

UnmanagedType.ByValTStr

Uma matriz de comprimento fixo de caractere; tipo da matriz é determinado pelo conjunto de caractere da estrutura do recipiente.

The ByValTStr tipo é usado para embutido tamanho fixo que aparecem dentro de uma estrutura de matrizes de caractere. Outros tipos de aplicam a referências de seqüência de caracteres contidas em estruturas que contêm ponteiros para as seqüências de caracteres.

The CharSet argumento das StructLayoutAttribute atributo é aplicado à estrutura contendo determina o formato de caractere seqüências de caracteres em estruturas. Seguintes estruturas de exemplo contêm referências de seqüência de caracteres e seqüências de caracteres embutida, bem sistema autônomo ANSI, Unicode e caracteres dependente de plataforma.

Representação de biblioteca de tipo

struct StringInfoA {
   char *    f1;
   char      f2[256];
};
struct StringInfoW {
   WCHAR *   f1;
   WCHAR     f2[256];
   BSTR      f3;
};
struct StringInfoT {
   TCHAR *   f1;
   TCHAR     f2[256];
};

O exemplo de código a seguir mostra como usar o MarshalAsAttribute atributo para definir a mesma estrutura em formatos diferentes.

<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Ansi)> _
Structure StringInfoA
<MarshalAs(UnmanagedType.LPStr)> Public f1 As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _
Public f2 As String
End Structure
<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Unicode)> _
Structure StringInfoW
<MarshalAs(UnmanagedType.LPWStr)> Public f1 As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _
Public f2 As String
<MarshalAs(UnmanagedType.BStr)> Public f3 As String
End Structure
<StructLayout(LayoutKind.Sequential, CharSet := CharSet.Auto)> _
Structure StringInfoT
<MarshalAs(UnmanagedType.LPTStr)> Public f1 As String
<MarshalAs(UnmanagedType.ByValTStr, SizeConst := 256)> _
Public f2 As String
End Structure
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
struct StringInfoA {
   [MarshalAs(UnmanagedType.LPStr)] public String f1;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
struct StringInfoW {
   [MarshalAs(UnmanagedType.LPWStr)] public String f1;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;
   [MarshalAs(UnmanagedType.BStr)] public String f3;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct StringInfoT {
   [MarshalAs(UnmanagedType.LPTStr)] public String f1;
   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;
}

Buffers de string de comprimento fixo

Em algumas circunstâncias, um buffer de caractere de comprimento fixo deve ser passado em código não gerenciado para ser manipulado.Simplesmente passar uma seqüência de caracteres não funciona nesse caso porque o chamador não é possível modificar o Sumário do buffer transmitido.Mesmo se a seqüência de caracteres é passada por referência, não é possível inicializar o buffer para um determinado dimensionar.

A solução é passar um StringBuilder buffer sistema autônomo o argumento em vez de uma seqüência de caracteres. A StringBuilder pode ser referência cancelada e modificados pelo computador chamado, fornecido não excede a capacidade do StringBuilder. Também pode ser inicializado para um comprimento fixo.Por exemplo, se você inicializar um StringBuilder para uma capacidade de buffer N, o empacotador fornece um buffer de dimensionar ()N+ 1) caracteres. As contas + 1 para o fato de que a seqüência de caracteres não-gerenciada tem um terminador nulo durante StringBuilder não ocorre.

Por exemplo, o Microsoft Win32 API GetWindowText função (definida em Windows.h) é um buffer de caractere de comprimento fixo que deve ser passado em código não gerenciado para ser manipulado. LpString aponta para um buffer alocado chamador de dimensionar nMaxCount. O chamador deve alocar o buffer e conjunto o nMaxCount argumento para o dimensionar do buffer alocado. O código a seguir mostra o GetWindowText declaração de função conforme definido no Windows.h.

int GetWindowText(
HWND hWnd,        // Handle to window or control.
LPTStr lpString,  // Text buffer.
int nMaxCount     // Maximum number of characters to copy.
);

A StringBuilder pode ser referência cancelada e modificados pelo computador chamado, fornecido não excede a capacidade do StringBuilder. O exemplo de código a seguir demonstra como StringBuilder pode ser inicializado para um comprimento fixo.

Public Class Win32API
Public Declare Auto Sub GetWindowText Lib "User32.Dll" _
(h As Integer, s As StringBuilder, nMaxCount As Integer)
End Class
Public Class Window
   Friend h As Integer ' Friend handle to Window.
   Public Function GetText() As String
      Dim sb As New StringBuilder(256)
      Win32API.GetWindowText(h, sb, sb.Capacity + 1)
   Return sb.ToString()
   End Function
End Class
public class Win32API {
[DllImport("User32.Dll")]
public static extern void GetWindowText(int h, StringBuilder s, 
int nMaxCount);
}
public class Window {
   internal int h;        // Internal handle to Window.
   public String GetText() {
      StringBuilder sb = new StringBuilder(256);
      Win32API.GetWindowText(h, sb, sb.Capacity + 1);
   return sb.ToString();
   }
}

Consulte também

Conceitos

Blittable e tipos Blittable não

Atributos direcionais

Copiando e fixação

Outros recursos

Comportamento de marshaling padrão