Compartilhar via


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 de módulo exportado

Conversão de membro exportado

Conversão do parâmetro exportado

Outros recursos

Conjunto de módulos (assembly) Type biblioteca conversão resumo