Personalizar o marshaling 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 marshalling de runtime 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, recomendamos usar MarshalUsingAttribute para a interoperabilidade gerada pela origem. Para obter mais informações, confira Marshaling personalizado para a geração de origem.
Personalizar parâmetros de cadeias de caracteres
O .NET tem uma variedade de formatos para a realização de marshalling de cadeias de caracteres. Esses métodos são divididos em seções distintas em strings no C-style e em formatos de cadeias de caracteres centrados no 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.
System.Runtime.InteropServices.UnmanagedType valor |
Codificação |
---|---|
LPStr | ANSI |
LPUTF8Str | UTF-8 |
LPWStr | UTF-16 |
LPTStr | UTF-16 |
O formato UnmanagedType.VBByRefStr é um pouco 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
. Recomendamos que você não use esse formato manualmente, pois ele pode 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 C-style, use o tipo não gerenciado UnmanagedType.LPArray. Se os valores na matriz precisarem de marshalling personalizado, você poderá 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 tipo não gerenciado UnmanagedType.SafeArray. O tipo padrão dos elementos do SAFEARRAY
pode ser visto na tabela sobre como personalizar campos object
. Você pode usar os campos MarshalAsAttribute.SafeArraySubType e MarshalAsAttribute.SafeArrayUserDefinedSubType para personalizar o tipo de elemento exato do SAFEARRAY
.
Personalizar parâmetros boolianos ou decimais
Para saber mais sobre como realizar marshalling de parâmetros boolianos ou decimais, consulte Personalizar marshalling de estrutura.
Personalizar parâmetros de objeto (somente Windows)
No Windows, o runtime do .NET fornece várias maneiras diferentes de realizar marshalling de parâmetros de objeto para 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 VARIANT
s. Consulte a documentação sobre como personalizar campos object
para um mapeamento entre tipos .NET e tipos VARIANT
.
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.