Conversão de tipo exportado
Este tópico descreve como o processo de exportar converte os seguintes tipos:
Classes
Interfaces
Tipos de valor
Enumerações
Em geral, tipos exportados mantêm o mesmo nome que tinham dentro de um assembly, excluindo o namespace associada ao nome gerenciado.Por exemplo, o tipo de A.B.IList o código a seguir exemplo converte em IList na biblioteca de tipos exportada. Um cliente COM pode se referir o tipo sistema autônomo IList em vez de A.B.IList.
Namespace A
Namespace B
Interface IList
…
End Interface
End Namespace
End Namespace
namespace A {
namespace B {
interface IList {
…
}
}
}
Com essa abordagem, nomes de tipo em um assembly podem potencialmente colidem como tipos em namespaces diferente podem ter o mesmo nome.Quando o processo de exportar detecta uma colisão, ele retém o namespace para eliminar ambigüidades nomes.O exemplo de código a seguir mostra dois espaços para nome com o mesmo nome de tipo.
Namespace A
Namespace B
Public Class LinkedList
Implements IList
End Class
Public Interface IList
End Interface
End Namespace
End Namespace
Namespace C
Public Interface IList
End Interface
End Namespace
namespace A {
namespace B {
public class LinkedList : IList {…}
public interface IList {…}
}
}
namespace C {
public interface IList {…}
}
A representação de biblioteca de tipo seguinte mostra a resolução do nome de cada tipo.Além disso, como períodos inválido são válido em nomes de tipo de biblioteca, o processo de exportar substitui cada período por sublinhados.
Representação de biblioteca de tipo
library Widgets
{
[…]
coclass LinkedList
{
interface A_B_IList
};
[…]
interface A_B_IList {…};
[…]
interface C_IList {…};
};
O processo de exportar também gera automaticamente um identificador programático (ProgId) combinando o namespace e o nome do tipo.Por exemplo, o ProgId gerado para o gerenciado LinkedList classe mostrado nos exemplos anteriores é A.B.LinkedList.
Combinando o namespace e nome de tipo pode resultar em um ProgId inválido.Um ProgId é limitado a 39 caracteres e não pode conter nenhum caractere de pontuação Outros que períodos.Para evitar essas limitações, você pode especificar um ProgId em seu código-fonte, aplicando o ProgIdAttribute, em vez de permitir que o processo de exportar gerar um identificador para você.
Classes
O processo de exportar converte cada classe pública (que omita o atributo de ComVisible (false)) em um assembly para uma coclass em uma biblioteca de tipo.Uma coclass exportado possui nem métodos propriedades; no entanto, ele retém o nome do gerenciado classe e implementa todas as interfaces implementada explicitamente pelo gerenciado classe.
O exemplo de código a seguir mostra a definição do IShape interface e o Circle classe, que implementa IShape. A representação de biblioteca de tipo convertido segue o exemplo de código.
Public Interface IShape
Sub Draw()
Sub Move(x As Integer, y As Integer)
End Interface
Class Circle
Implements IShape
Sub Draw Implements IShape.Draw
…
Sub Move(x As Integer, y As Integer) Implements IShape.Move
…
Sub Enlarge(x As Integer)
…
End Class
public interface IShape {
void Draw();
void Move(int x, int y);
}
class Circle : IShape {
void Draw();
void Move(int x, int y);
void Enlarge(int x);
}
Representação de biblioteca de tipo
[ uuid(…), dual, odl, oleautomation ]
interface IShape : IDispatch {
HRESULT Draw();
HRESULT Move(int x, int y);
}
[ uuid(…) ]
coclass Circle {
interface IShape;
}
Cada coclass pode implementar uma interface, chamada de interface de classe, o processo de exportar pode gerar automaticamente.A interface de classe expõe todos os métodos e propriedades disponível no original gerenciado classe, assim permitindo que os clientes COM acessá-las, chamada por meio da interface de classe.
Você pode atribuir um identificador universal exclusivo (UUID) específico a classe aplicando o GuidAttribute imediatamente acima do gerenciado definição de classe.Durante o processo de conversão, o processo de exportar transfere o valor fornecido para o GuidAttribute para o UUID na biblioteca de tipos.Caso contrário, o processo de exportar obtém UUIDs de um hash que inclui o nome completo da classe, incluindo o espaço para nome.Usando o nome completo garante que uma classe com um determinado nome de um dado namespace sempre gera o mesmo UUID e que duas classes com nomes diferentes nunca geram o mesmo UUID.
Classes abstratas e classes sem construtores públicos, são marcados com o noncreatable atributo de biblioteca de tipo.Outros atributos da biblioteca de tipo que se aplicam a coclasses, por exemplo, licenciado, oculto, restrito, and controle não são definidas.
Interfaces
O processo de exportar converte interfaces gerenciadas em interfaces COM sistema autônomo mesmos métodos e propriedades sistema autônomo a interface gerenciada, mas sistema autônomo assinaturas de método diferem consideravelmente.
Identidades de interface
Interfaces COM incluem um identificador de interface (IID) para diferenciar uma interface do outro.Você pode atribuir um IID fixa para qualquer gerenciado interface aplicando o GuidAttribute atributo.Se você omite esse atributo e não atribua um IID fixo, o processo de exportar atribuirá automaticamente uma durante a conversão.Um IID atribuído pelo tempo de execução compreende o nome da interface (incluindo o espaço para nome) e a assinatura completa de todos os métodos definidos dentro da interface.Por reordenar os métodos no gerenciado interface ou alterando o argumento de método e os tipos de retorno, você alterar a IID atribuída a essa interface.Alterar um nome de método não afeta a IID.
Usando o QueryInterface método implementado pelo tempo de execução, COM clientes podem obter uma interface ter um IID fixo ou IID atribuído pelo tempo de execução.IIDs gerados pelo tempo de execução não são persistentes nos metadados do tipo.
Tipos de interface
A menos que você especifique o contrário, o processo de exportar converte todos gerenciado interfaces para interfaces duplas em uma biblioteca de tipos.Duas interfaces permitem que os clientes COM escolher entre ligação antecipada e atrasada.
Você pode aplicar o InterfaceTypeAttribute atributo a uma interface para seletivamente indicar que a interface deve ser exportada sistema autônomo uma interface dupla, uma interface derivada de IUnknown ou uma interface somente de despacho (dispinterface).Todas as interfaces exportadas estendem diretamente de qualquer um dos IUnknown or IDispatch, independentemente de sua hierarquia de herança em código gerenciado.
O exemplo de código a seguir mostra os valores opcionais para controlar o tipo de interface.Depois de exportado para uma biblioteca de tipos, essas opções produzem os resultados mostrados na representação de biblioteca de tipo que segue o código.
' Creates a Dual interface by default.
Public Interface InterfaceWithNoInterfaceType
Sub test()
End Interface
' Creates a Dual interface explicitly.
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface InterfaceWithInterfaceIsDual
Sub test()
End Interface
' Creates an IUnknown interface (not dispatch).
<InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface InterfaceWithInterfaceIsIUnknown
Sub test()
End Interface
' Creates a Dispatch-only interface (dispinterface).
<InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface InterfaceWithInterfaceIsIDispatch
Sub test()
End Interface
// Creates a Dual interface by default.
public interface InterfaceWithNoInterfaceType {
void test();
}
// Creates a Dual interface explicitly.
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface InterfaceWithInterfaceIsDual {
void test();
}
// Creates an IUnknown interface (not dispatch).
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface InterfaceWithInterfaceIsIUnknown {
void test();
}
// Creates a Dispatch-only interface(dispinterface).
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface InterfaceWithInterfaceIsIDispatch {
void test();
}
Representação de biblioteca de tipo
[ odl, uuid(…), dual, oleautomation ]
interface InterfaceWithNoInterfaceType : IDispatch {
HRESULT test();
};
[ odl, uuid(…), dual, oleautomation ]
interface InterfaceWithInterfaceIsDual : IDispatch {
HRESULT test();
};
[ odl, uuid(…), oleautomation ]
interface InterfaceWithInterfaceIsIUnknown : IUnknown {
HRESULT test();
};
[ uuid(…) ]
dispinterface InterfaceWithInterfaceIsIDispatch {
properties:
methods:
void test();
};
A maioria das interfaces são marcadas com o odl, and oleautomation atributos da biblioteca de tipo durante o processo de exportar.(Dispinterfaces são a exceção).Duas interfaces são marcados com o duplo atributo de biblioteca de tipo.Uma interface dupla deriva o IDispatch interface, mas ele também expõe vtable slots para seus métodos.
Interfaces de classe
Para obter uma descrição completa da interface da classe e recomendações de uso, consulte Apresentando a interface de classe.O processo de exportar pode gerar essa interface automaticamente em nome de uma classe gerenciada sem uma interface definida explicitamente no código gerenciado.Clientes COM não é possível acessar diretamente métodos de classe.
O exemplo de código a seguir mostra uma classe base e uma classe derivada.Nenhuma classe implementa uma interface explícita.O processo de exportar oferece uma interface de classe para ambos gerenciado classes.
Public Class BaseClassWithClassInterface
Private Shared StaticPrivateField As Integer
Private PrivateFld As Integer
Private Property PrivateProp() As Integer
Get
Return 0
End Get
Set
End Set
End Property
Private Sub PrivateMeth()
Return
End Sub
Friend Shared StaticInternalField As Integer
Friend InternalFld As Integer
Friend Property InternalProp() As Integer
Get
Return 0
End Get
Set
End Set
End Property
Friend Sub InternalMeth()
Return
End Sub
Public Shared StaticPublicField As Integer
Public PublicFld As Integer
Public Property PublicProp() As Integer
Get
Return 0
End Get
Set
End Set
End Property
Public Sub PublicMeth()
Return
End Sub
End Class
Public Class DerivedClassWithClassInterface
Inherits BaseClassWithClassInterface
Public Sub Test()
Return
End Sub
End Class
public class BaseClassWithClassInterface {
private static int StaticPrivateField;
private int PrivateFld;
private int PrivateProp{get{return 0;} set{;}}
private void PrivateMeth() {return;}
internal static int StaticInternalField;
internal int InternalFld;
internal int InternalProp{get{return 0;} set{;}}
internal void InternalMeth() {return;}
public static int StaticPublicField;
public int PublicFld;
public int PublicProp{get{return 0;} set{;}}
public void PublicMeth() {return;}
}
public class DerivedClassWithClassInterface : BaseClassWithClassInterface {
public void Test() {return;}
}
Representação de biblioteca de tipo
[odl,uuid(…), hidden, dual, nonextensible, oleautomation]
interface _BaseClassWithClassInterface : IDispatch {
[id(00000000),propget] HRESULT ToString([out, retval] BSTR* p);
[id(0x60020001)] HRESULT Equals([in] VARIANT obj,
[out, retval] VARIANT_BOOL* p);
[id(0x60020002)] HRESULT GetHashCode([out,retval] long* p);
[id(0x60020003)] HRESULT GetType([out, retval] _Type** p);
[id(0x60020004),propget] HRESULT PublicProp([out,retval] long* p);
[id(0x60020004),propput] HRESULT PublicProp([in] long p);
[id(0x60020006)] HRESULT PublicMeth();
[id(0x60020007),propget] HRESULT PublicFld([out, retval]long* p);
[id(0x60020007),propput] HRESULT PublicFld([in] long p);
};
[odl,uuid(…), hidden, dual, nonextensible, oleautomation]
interface _DerivedClassWithClassInterface : IDispatch {
[id(00000000),propget] HRESULT ToString([out, retval] BSTR* p);
[id(0x60020001)] HRESULT Equals([in] VARIANT obj,
[out, retval] VARIANT_BOOL* p);
[id(0x60020002)] HRESULT GetHashCode([out,retval] long* p);
[id(0x60020003)] HRESULT GetType([out, retval] _Type** p);
[id(0x60020004),propget] HRESULT PublicProp([out,retval] long* p);
[id(0x60020004),propput] HRESULT PublicProp([in] long p);
[id(0x60020006)] HRESULT PublicMeth();
[id(0x60020007),propget] HRESULT PublicFld([out, retval]long* p);
[id(0x60020007),propput] HRESULT PublicFld([in] long p);
[id(0x60020008)] HRESULT Test();
}
As interfaces de classe exportado têm as seguintes características:
Cada interface de classe retém o nome do gerenciado de classe, mas é prefixada com um sublinhado.Quando um conflitos de nome de interface com um nome de interface definida anteriormente, o novo nome é anexado com um sublinhado e um número incremental.Por exemplo, o próximo nome disponível para _ClassWithClassInterface é _ClassWithClassInterface_2.
O processo de exportar sempre gera novos identificadores de interface (IID).Não é possível conjunto explicitamente o IID da interface de classe.
Por padrão, ambas as interfaces de classe derivam de interfaces de IDispatch.
As interfaces têm ODL, duplo, oculto, nonextensible e oleautomation atributos.
Ambas as interfaces têm todos os membros públicos da sua classe base (sistema.objeto).
Eles não contêm membros privados ou internos da classe.
Cada membro é automaticamente atribuído um DispId exclusivo.O DispIds podem ser definida explicitamente pela aplicação DispIdAttribute para o membro da classe.
Assinaturas de método são transformadas retornar HRESULTs e [out, retval] Parâmetros.
Os campos e propriedades são transformados em [propget], [propput] e [propputref].
Interface padrão
COM tem a noção de uma interface padrão.Membros da interface padrão são tratados sistema autônomo membros da classe de ligação tardia idiomas sistema autônomo o Visual Basic.No .NET estrutura, não é necessário para uma interface padrão como próprias classes podem ter membros.No entanto, ao expor classes COM, classes são muito mais fácil de usar que eles tenham uma interface padrão.
Quando um gerenciado classe é exportado para uma biblioteca de tipos sistema autônomo uma coclass, uma interface é normalmente identificada sistema autônomo interface padrão para a classe.Se nenhuma interface for identificada sistema autônomo o padrão na biblioteca de tipos, a maioria dos aplicativos COM pressupõem que a primeira interface implementada é a interface padrão do que coclass.
sistema autônomo mostra o exemplo de código a seguir, o processo de exportar converte uma classe gerenciada que não tem nenhuma interface de classe e marca a primeira interface implementada sistema autônomo padrão na biblioteca de tipos exportados.A representação de biblioteca de tipo da classe convertida segue o exemplo de código.
<ClassInterface(ClassInterfaceType.None)> _
Public Class ClassWithNoClassInterface
Implements IExplicit
Implements IAnother
Sub M()
…
End Class
[ClassInterface(ClassInterfaceType.None)]
public class ClassWithNoClassInterface : IExplicit, IAnother {
void M();
}
Representação de biblioteca de tipo
coclass ClassWithNoClassInterface {
[default] IExplicit;
IAnother;
}
O processo de exportar sempre marca o interface de classe sistema autônomo interface padrão para a classe, independentemente de qualquer interface que a classe implementa explicitamente.O exemplo a seguir mostra duas classes.
<ClassInterface(ClassInterfaceType.AutoDispatch)> _
Public Class ClassWithAutoDispatch
Implements IAnother
Sub M()
…
End Class
<ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class ClassWithAutoDual
Implements IAnother
Sub M()
…
End Class
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class ClassWithAutoDispatch : IExplicit, IAnother {
void M();
}
[ClassInterface(ClassInterfaceType.AutoDual)]
public class ClassWithAutoDual : IExplicit, IAnother {
void M();
}
Representação de biblioteca de tipo
// ClassWithAutoDispatch: IDispatch
coclass ClassWithAutoDispatch {
[default] _ClassWithAutoDispatch;
interface _Object;
IExplicit;
IAnother;
}
interface _ClassWithAutoDual {…}
coclass ClassWithAutoDual {
[default] _ClassWithAutoDual;
IExplicit;
IAnother;
}
Tipos de valor
Tipos de valor (sistema autônomo tipos que se estendem sistema.Value) são exportadas para bibliotecas de tipos sistema autônomo estruturas de estilo C com a definição de tipo.O layout dos membros da estrutura é controlado com o StructLayoutAttribute atributo, que é aplicado ao tipo. Somente os campos do tipo de valor são exportados.Se um tipo de valor tem métodos, são inacessíveis do COM.
Por exemplo:
[StructLayout(LayoutKind.Sequential)]
public struct Point {
int x;
int y;
public void SetXY(int x, int y){
this.x = x;
this.y = y;
}
};
O tipo de valor de ponto é exportado para COM sistema autônomo um ponto de typedef, conforme mostrado no exemplo a seguir:
typedef
[uuid(…)]
struct tagPoint {
short x;
short y;
} Point;
Observe que o processo de conversão remove o método SetXY a typedef.
Enumerações
O processo de exportar adiciona um gerenciado enumeração para bibliotecas de tipos sistema autônomo uma enumeração com sistema autônomo nomes de membro alteradas para garantir que o membro exclusivo de nomeação.Para garantir que cada membro nome seja exclusivo, Tlbexp.exe prefixos de um sublinhado como o nome da enumeração para cada membro durante o processo de exportar.Por exemplo, a enumeração simples seguinte produz um conjunto de representações de biblioteca de tipo.
Enum DaysOfWeek {
Sunday = 0;
Monday;
Tuesday;
…
};
Representação de biblioteca de tipo
enum DaysOfWeek {
DaysOfWeek_Sunday = 0;
DaysOfWeek_Monday;
DaysOfWeek_Tuesday;
…
};
Os escopos de tempo de execução gerenciado os membros da enumeração enumeração na qual eles pertencem.Por exemplo, todas as referências a Sunday no DaysOfWeek enumeração, mostrada no exemplo anterior, deve ser qualificada com DaysOfWeek. Não é possível fazer referência a Sunday em vez de DaysOfWeek.Sunday. Nomes de membro exclusivo é um requisito de COM enumerações.
Consulte também
Conceitos
Conversão de assembly exportados
Conversão do parâmetro exportado
Outros recursos
Conjunto de módulos (assembly) Type biblioteca conversão resumo