Partilhar via


Exemplo de seqüências de caracteres

Este exemplo demonstra como usar uma seqüência de caracteres retornada de uma função não gerenciada e como passar uma estrutura que contém uma seqüência de caracteres formatada em Unicode ou ANSI-formatado.Ele mostra como inicializar corretamente essas seqüências de caracteres e como recuperar os valores retornados.

O exemplo de string utiliza as seguintes funções não gerenciadas, mostradas com sua declaração de função original:

  • TestStringAsResult exportados de PinvokeLib.dll.

    char* TestStringAsResult();
    
  • TestStringInStruct exportados de PinvokeLib.dll.

    void TestStringInStruct(MYSTRSTRUCT* pStruct);
    
  • TestStringInStructAnsi exportados de PinvokeLib.dll.

    void TestStringInStructAnsi(MYSTRSTRUCT2* pStruct);
    

PinvokeLib.dll é uma biblioteca de não gerenciada personalizada que contém implementações para as funções listadas anteriormente e duas estruturas, MYSTRSTRUCT and MYSTRSTRUCT2.Essas estruturas de contenham os seguintes elementos:

typedef struct _MYSTRSTRUCT
{
   wchar_t* buffer;
   UINT size; 
} MYSTRSTRUCT;
typedef struct _MYSTRSTRUCT2
{
   char* buffer;
   UINT size; 
} MYSTRSTRUCT2;

Neste exemplo, o gerenciado MyStrStruct e MyStrStruct2 estruturas de contenham seqüências de caracteres gerenciadas em vez de StringBuilder buffers porque o StringBuilder tipo não pode ser usado dentro de uma estrutura.The StructLayoutAttribute atributo é definido para garantir que os membros são organizados em memória seqüencialmente, na ordem em que aparecem. The Conjunto de caracteres campo está definido para especificar ANSI ou Unicode formata.

The LibWrap classe contém os métodos de protótipo gerenciado chamados pela App classe. Embora as estruturas normalmente são passadas por valor, os argumentos para o TestStringInStruct e TestStringInStructAnsi métodos são marcados com o ref (ByRefpalavra- no Visual Basic) chave, que passa estruturas por referência.

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 each unmanaged structure.
< StructLayout( LayoutKind.Sequential, CharSet:=CharSet.Unicode )> _
Public Structure MyStrStruct
   Public buffer As String
   Public size As Integer
End Structure 'MyStrStruct

< StructLayout( LayoutKind.Sequential, CharSet:=CharSet.Ansi )> _
Public Structure MyStrStruct2
   Public buffer As String
   Public size As Integer
End Structure 'MyStrStruct2

Public Class LibWrap
   ' Declares managed prototypes for unmanaged functions.
   Declare Function TestStringAsResult Lib "..\LIB\PinvokeLib.dll" () _
      As String
   Declare Sub TestStringInStruct Lib "..\LIB\PinvokeLib.dll" _
      ( ByRef mss As MyStrStruct )
   Declare Sub TestStringInStructAnsi Lib "..\LIB\PinvokeLib.dll" _
      ( ByRef mss As MyStrStruct2 )
End Class 'LibWrap
// Declares a managed structure for each unmanaged structure.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Unicode )]
public struct MyStrStruct 
{  
   public String buffer;
   public int size;
}
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyStrStruct2 
{  
   public String buffer;
   public int size;
}
public class LibWrap
{
   // Declares managed prototypes for unmanaged functions.
   [DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern String TestStringAsResult();

   [DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern void TestStringInStruct( ref MyStrStruct mss );

   [DllImport( "..\\LIB\\PinvokeLib.dll" )]
   public static extern void TestStringInStructAnsi( ref MyStrStruct2 
      mss );
}

Chamando funções

Public Class App
   Public Shared Sub Main()
      ' String as result.
      Dim strng As String = LibWrap.TestStringAsResult()
      Console.WriteLine( ControlChars.CrLf + "String returned: {0}", _
      strng )

      ' Initializes buffer and appends something to the end so the whole
      ' buffer is passed to the unmanaged side.
      Dim buffer As New StringBuilder( "content", 100 )
      buffer.Append( ChrW(0) )
      buffer.Append( "*"c, buffer.Capacity - 8)
      
      Dim mss As MyStrStruct
      mss.buffer = buffer.ToString()
      mss.size = mss.buffer.Length
      
      LibWrap.TestStringInStruct( mss )
      Console.WriteLine( ControlChars.CrLf + _
         "Buffer after Unicode function call: {0}", mss.buffer )

      Dim buffer2 As New StringBuilder( "content", 100 )
      buffer2.Append( ChrW(0) )
      buffer2.Append( "*"c, buffer2.Capacity - 8 )
      
      Dim mss2 As MyStrStruct2
      mss2.buffer = buffer2.ToString()
      mss2.size = mss2.buffer.Length 
      
      LibWrap.TestStringInStructAnsi( mss2 )
      Console.WriteLine( ControlChars.CrLf + _
         "Buffer after Ansi function call: {0}", mss2.buffer )
   End Sub 'Main
End Class 'App
public class App
{
   public static void Main()
   {
      // String as result.
      String str = LibWrap.TestStringAsResult();
      Console.WriteLine( "\nString returned: {0}", str );
      
      // Initializes buffer and appends something to the end so the whole
      // buffer is passed to the unmanaged side.
      StringBuilder buffer = new StringBuilder( "content", 100 ); 
      buffer.Append( (char)0 );
      buffer.Append( '*', buffer.Capacity - 8 );
      
      MyStrStruct mss;
      mss.buffer = buffer.ToString();
      mss.size = mss.buffer.Length;
      
      LibWrap.TestStringInStruct( ref mss );
      Console.WriteLine( "\nBuffer after Unicode function call: {0}", 
         mss.buffer );
      
      StringBuilder buffer2 = new StringBuilder( "content", 100 ); 
      buffer2.Append( (char)0 );
      buffer2.Append( '*', buffer2.Capacity - 8 );
      
      MyStrStruct2 mss2;
      mss2.buffer = buffer2.ToString();
      mss2.size = mss2.buffer.Length;
      
      LibWrap.TestStringInStructAnsi( ref mss2 );
      Console.WriteLine( "\nBuffer after Ansi function call: {0}", 
         mss2.buffer );
   }
}

Consulte também

Tarefas

Invocação de plataforma Tecnologia Exemplo

Conceitos

marshaling de strings

Tipos de dados de invocação de plataforma

Padrão de marshaling de strings

Criando protótipos em código gerenciado