Como: Criar wrappers manualmente
Se você decidir declarar tipos COM manualmente no código-fonte gerenciado, o melhor lugar para começar é com um arquivo IDL (Interface Definition Language) existente ou biblioteca de tipos. Quando você não tem o arquivo IDL ou não pode gerar um arquivo de biblioteca de tipos, você pode simular os tipos COM criando declarações gerenciadas e exportando o assembly resultante para uma biblioteca de tipos.
Para simular tipos COM de origem gerenciada
Declare os tipos em um idioma compatível com a Common Language Specification (CLS) e compile o arquivo.
Exporte o assembly que contém os tipos com o Exportador de Biblioteca de Tipos (Tlbexp.exe).
Use a biblioteca de tipos COM exportada como base para declarar tipos gerenciados orientados a COM.
Para criar um wrapper chamável (RCW) em tempo de execução
Supondo que você tenha um arquivo IDL ou um arquivo de biblioteca de tipos, decida quais classes e interfaces deseja incluir no RCW personalizado. Você pode excluir quaisquer tipos que não pretenda usar direta ou indiretamente em seu aplicativo.
Crie um arquivo de origem em um idioma compatível com CLS e declare os tipos. Consulte Biblioteca de tipos para resumo de conversão de montagem para obter uma descrição completa do processo de conversão de importação. Efetivamente, quando cria um RCW personalizado, está a executar manualmente a atividade de conversão de tipos fornecida pelo Importador de Biblioteca de Tipos (Tlbimp.exe). O exemplo na próxima seção mostra tipos em um IDL ou arquivo de biblioteca de tipos e seus tipos correspondentes no código C#.
Quando as declarações estiverem concluídas, compile o arquivo como você compila qualquer outro código-fonte gerenciado.
Tal como acontece com os tipos importados com Tlbimp.exe, alguns requerem informações adicionais, que você pode adicionar diretamente ao seu código. Para obter detalhes, consulte Como editar assemblies de interoperabilidade.
Exemplo
O código a seguir mostra um exemplo da interface e SATest
classe ISATest
no IDL e os tipos correspondentes no código-fonte C#.
IDL ou arquivo de biblioteca de tipos
[
object,
uuid(40A8C65D-2448-447A-B786-64682CBEF133),
dual,
helpstring("ISATest Interface"),
pointer_default(unique)
]
interface ISATest : IDispatch
{
[id(1), helpstring("method InSArray")]
HRESULT InSArray([in] SAFEARRAY(int) *ppsa, [out,retval] int *pSum);
};
[
uuid(116CCA1E-7E39-4515-9849-90790DA6431E),
helpstring("SATest Class")
]
coclass SATest
{
[default] interface ISATest;
};
Wrapper no código-fonte gerenciado
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
[assembly:Guid("E4A992B8-6F5C-442C-96E7-C4778924C753")]
[assembly:ImportedFromTypeLib("SAServerLib")]
namespace SAServer
{
[ComImport]
[Guid("40A8C65D-2448-447A-B786-64682CBEF133")]
[TypeLibType(TypeLibTypeFlags.FLicensed)]
public interface ISATest
{
[DispId(1)]
//[MethodImpl(MethodImplOptions.InternalCall,
// MethodCodeType=MethodCodeType.Runtime)]
int InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
[ComImport]
[Guid("116CCA1E-7E39-4515-9849-90790DA6431E")]
[ClassInterface(ClassInterfaceType.None)]
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
public class SATest : ISATest
{
[DispId(1)]
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime)]
extern int ISATest.InSArray( [MarshalAs(UnmanagedType.SafeArray,
SafeArraySubType=VarEnum.VT_I4)] ref int[] param );
}
}