Compartilhar via


Personalizar a organização de parâmetros

Quando o comportamento de marshalling de parâmetro padrão do runtime do .NET não fizer o que você deseja, use o atributo System.Runtime.InteropServices.MarshalAsAttribute para personalizar o modo como os parâmetros passam pelo processo de marshalling. Esses recursos de personalização não se aplicam quando o runtime marshaling está desabilitado.

Observação

A interoperabilidade gerada pela origem para P/Invokes e COM respeita apenas um pequeno subconjunto de MarshalAsAttribute em parâmetros. Em vez disso, é recomendável usar MarshalUsingAttribute para interoperabilidade gerada por meio do código-fonte. Para obter mais informações, confira Marshaling personalizado para a geração de origem.

Personalizando parâmetros de cadeia de caracteres

O .NET possui uma variedade de formatos para a manipulação de strings. Esses métodos são divididos em seções distintas sobre cadeias de caracteres de estilo C e formatos de cadeia de caracteres voltados para o Windows.

Cadeias de caracteres C-style

Cada um desses formatos passa uma cadeia de caracteres terminada em nulo para o código nativo. Eles diferem pela codificação da cadeia de caracteres nativa.

Valor System.Runtime.InteropServices.UnmanagedType Codificação
LPStr ANSI
LPUTF8Str UTF-8
LPWStr UTF-16
LPTStr UTF-16

O UnmanagedType.VBByRefStr formato é ligeiramente diferente. Como LPWStr, ele realiza marshalling da cadeia de caracteres para uma cadeia de caracteres C-style nativa codificada em UTF-16. No entanto, a assinatura gerenciada passa a cadeia de caracteres por referência e a assinatura nativa correspondente usa a cadeia de caracteres por valor. Essa distinção permite que você use uma API nativa que recebe uma cadeia de caracteres por valor e a modifica no local sem precisar usar um StringBuilder. É recomendável não usar manualmente esse formato, pois ele é propenso a causar confusão com as assinaturas nativas e gerenciadas incompatíveis.

Formatos de cadeias de caracteres centradas no Windows

Ao interagir com interfaces COM ou OLE, você provavelmente descobrirá que as funções nativas tomam cadeias de caracteres como argumentos BSTR. Você pode usar o tipo não gerenciado UnmanagedType.BStr para realizar marshalling de uma cadeia de caracteres como um BSTR.

Se você estiver interagindo com as APIs do WinRT, poderá usar o formato UnmanagedType.HString para realizar marshalling de uma cadeia de caracteres como HSTRING.

Personalizar parâmetros de matriz

.NET também fornece várias maneiras de realizar marshalling de parâmetros de matriz. Se você estiver chamando uma API que usa uma matriz de estilo C, use o UnmanagedType.LPArray tipo não gerenciado. Se os valores na matriz precisarem de processamento personalizado, você pode usar o campo ArraySubType no atributo [MarshalAs] para isso.

Se você estiver usando APIs COM, provavelmente terá que organizar seus parâmetros de matriz como SAFEARRAY*s. Para fazer isso, você pode usar o UnmanagedType.SafeArray tipo não gerenciado. O tipo padrão dos elementos do SAFEARRAY pode ser visto na tabela sobre a personalização de object campos. Você pode usar os MarshalAsAttribute.SafeArraySubType campos e MarshalAsAttribute.SafeArrayUserDefinedSubType para personalizar o tipo de elemento exato do SAFEARRAY.

Personalizando parâmetros boolianos ou decimais

Para saber mais sobre como realizar marshalling de parâmetros boolianos ou decimais, consulte Personalizar marshalling de estrutura.

Personalizando parâmetros de objeto (somente Windows)

No Windows, o sistema de execução do .NET fornece várias maneiras de converter parâmetros de objeto para o código nativo.

Marshalling como interfaces COM específicas

Se sua API leva um ponteiro para um objeto COM, você pode usar qualquer um dos seguintes formatos UnmanagedType em um parâmetro de tipo object para informar o .NET para realizar marshalling como essas interfaces específicas:

  • IUnknown
  • IDispatch
  • IInspectable

Além disso, se o seu tipo estiver marcado com [ComVisible(true)] ou se você estiver organizando o tipo object, poderá usar o formato UnmanagedType.Interface para realizar marshalling do seu objeto como um COM callable wrapper para a exibição COM do seu tipo.

Marshalling para uma VARIANT

Se sua API nativa tiver uma VARIANT Win32, você poderá usar o formato UnmanagedType.Struct no seu object para organizar seus objetos como VARIANTs. Consulte a documentação sobre como personalizar object campos para um mapeamento entre tipos e VARIANT tipos do .NET.

Marshallers personalizados

Se você deseja projetar uma interface COM nativa em um tipo gerenciado diferente, você pode usar o formato UnmanagedType.CustomMarshaler e uma implementação de ICustomMarshaler para fornecer seu próprio código de marshaling personalizado.