Conversão de membro exportado
Este tópico descreve como o processo de exportação converte os seguintes membros:
Métodos
Propriedades
Eventos
Métodos
Clientes COM esperam chamar métodos, passando os tipos de dados COM familiares como, por exemplo, parâmetros e recebendo HRESULTs em retorno. No.NET território, entretanto, suas classes não tem nenhuma restrição sobre tipos de retorno (e, na verdade, não use HRESULTs).
Para atender a ambos os modelos, cada método de um tipo gerenciado tem um.NET assinatura e uma assinatura de COM implícita. Duas assinaturas são geralmente muito diferentes. .Os clientes NET interagem com o servidor usando o.Assinatura NET enquanto (possivelmente ao mesmo tempo) os clientes COM interagem com o servidor usando a assinatura de COM. O servidor implementa o método com o.NET assinatura e o tempo de execução do serviço de empacotamento é responsável por fornecer um stub com a assinatura COM que delega a chamada para o método gerenciado.
HRESULT tradução
Uma assinatura gerenciada é convertida para uma assinatura não gerenciada, alterando o valor de retorno de gerenciado para um [out, retval] retornam valor de parâmetro e a alteração do tipo de não gerenciado para o HRESULT. Por exemplo, o DoSomething método pode ter as seguintes assinaturas:
Assinatura gerenciada
short DoSomething(short i);
Assinatura não gerenciada
HRESULT DoSomething([in] short i, [out, retval] short *rv);
Observe que a assinatura COM retorna um HRESULT e tem um parâmetro para o valor de retorno out adicionais. O valor de retorno da implementação gerenciada sempre retorna como um [out, retval] parâmetro adicionado ao final da assinatura não gerenciada, enquanto a assinatura não gerenciada sempre retorna um HRESULT. Se o método gerenciado tiver um retorno de void, o runtime omite [out, retval] parâmetro. Por exemplo:
Assinatura gerenciada
void DoSomething(short i);
Assinatura não gerenciada
HRESULT DoSomething([in] short i);
Em algumas circunstâncias, é preferível deixar a assinatura gerenciada inalterada. Você pode usar o PreserveSigAttribute para fazer isso. Por exemplo:
Assinatura gerenciada
[PreserveSig] short DoSomething(short i);
Assinatura não gerenciada
short DoSomething ([in] short i);
Ter duas assinaturas de método distinct torna fácil de usar a classe COM e.NET clientes perfeitamente. Além disso, tanto o COM e.Os clientes de rede podem usar um.NET classe simultaneamente. Como o autor da classe, você pode implementar apenas com a assinatura gerenciada. Usar Tlbexp. exe (ou uma API equivalente) automaticamente exporta a assinatura a uma biblioteca de tipos gerada para a classe.
Métodos sobrecarregados
Embora.NET oferece suporte à sobrecarga de métodos, o IDispatch interface depende exclusivamente o nome do método de ligação, em vez da assinatura do método completo. Portanto, não é capaz de oferecer suporte a métodos sobrecarregados. No entanto, para fornecer acesso aos métodos sobrecarregados de um tipo, Tlbexp. exe decora os nomes dos métodos sobrecarregados com um número ordinal para que cada nome de método seja exclusivo.
Gerenciado a seguir e as assinaturas não gerenciadas mostram a inclusão de números:
Assinatura gerenciada
interface INew {
public:
void DoSomething();
void DoSomething(short s);
void DoSomething(short l);
void DoSomething(float f);
void DoSomething(double d);
}
Assinatura não gerenciada
interface INew {
void DoSomething();
void DoSomething_2(short s);
void DoSomething_3(short l);
void DoSomething_4(float f);
void DoSomething_5(double d);
}
A assinatura COM os métodos aparece como um único DoSomething decorado do método seguido por uma série de DoSomething_x métodos, onde x começa em 2 e incrementos para cada forma do método de sobrecarregado. Observe que alguns dos métodos sobrecarregados podem ser herdada de um tipo base. No entanto, não há nenhuma garantia de que sobrecarregado métodos manterá o mesmo número que os avanços de versão do tipo.
Embora.NET clientes podem usar o formulário de sobrecarga do método, clientes COM tem que acessar os métodos decorados. Os navegadores de objeto exibem todos os formulários do método decorado com a assinatura do método permitem que você selecione o método correto. O cliente da ligação tardia também pode chamar IDispatch::GetIdsOfNames, passing o nome decorado para obter o DispID de qualquer método sobrecarregado.
Propriedades
Interfaces e classes gerenciadas podem ter propriedades. Uma propriedade gerenciada é de um tipo de dados específicos que pode ter um tipo de método de obter e definir o método. Esses métodos são definidos separadamente, assim como qualquer outro método. O exemplo de código a seguir mostra uma interface que contém um Height propriedade. Classes que implementam a interface são necessários para fornecer um get e definir o método da propriedade.
interface IMammal {
IMammal Mother{get;set;}
IMammal Father{get;set;}
int Height{get;set;}
int Weight{get;set;}
}
class Human : IMammal
{
int weight;
int height;
IMammal father;
IMammal mother;
public IMammal Mother { get { return mother; } set { mother = value; } }
public IMammal Father { get { return father; } set { father = value; } }
public int Height { get { return height; } set { height = value; } }
public int Weight { get { return weight; } set { weight = value; } }
}
Durante a exportação Tlbexp. exe converte o método de conjunto de propriedade para [propput] e o método get para [propget]. O nome da propriedade COM permanece igual ao nome de propriedade gerenciada. Essa regra tem as seguintes exceções:
Se o tipo de propriedade, excluindo os tipos de valor, é uma classe ou interface, o método do conjunto de propriedade se torna [propputref], fornecendo os parâmetros de um nível adicional de indireção.
Se a propriedade tiver não obter ou definir o método, Tlbexp. exe omite a propriedade da biblioteca de tipos.
Como propriedades, campos gerenciados são exportados para a biblioteca de tipos. Tempo de execução do serviço de empacotamento automaticamente gera o get e definir métodos de todos os campos públicos. Durante o processo de conversão, Tlbexp. exe gera [propput] (ou [propputref]) função e uma função [propget] para cada campo, como mostra a representação de biblioteca tipo seguinte.
Representação de biblioteca de tipo
interface IMammal : IDispatch {
[propget] HRESULT Mother([out, retval] IMammal** pRetVal);
[propputref] HRESULT Mother([in] IMammal* pRetVal);
[propget] HRESULT Father([out, retval] IMammal** pRetVal);
[propputref] HRESULT Father([in] IMammal* pRetVal);
[propget] HRESULT Height([out, retval] long* pRetVal);
[propput] HRESULT Height([in] long pRetVal);
[propget] HRESULT Weight([out, retval] long* pRetVal);
[propput] HRESULT Weight([in] long pRetVal);
[propget] HRESULT Age([out, retval] long* pRetVal);
[propput] HRESULT Age([in] long pRetVal);
};
Eventos
Se você não estiver familiarizado com o modelo de eventos de interoperabilidade COM, consulte gerenciados e não gerenciados eventos. Gerenciado tipos implementar eventos usando um modelo de evento de base do delegado. Por exemplo, o Class1Events interface no exemplo de código a seguir gera a Click de evento.
Public Delegate Sub ClickDelegate()
<GuidAttribute("1A585C4D-3371-48dc-AF8A-AFFECC1B0967"), _
InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)>
Public Interface Class1Event
Sub Click ()
End Interface
<ComSourceInterfaces("Class1Event, EventSrc")> _
Public Class Class1
Public Event Click As ClickDelegate
End Class
public delegate void Click();
public interface Class1Event
{
void Click();
}
[ComSourceInterfaces("Class1Event, EventSrc")]
public class Class1
{
public event ClickDelegate Click;
}
Durante a exportação, a Tlbexp. exe marca a interface de eventos como a fonte de seu coclass. Como mostra o seguinte tipo biblioteca representação, o arquivo ComClass1Events interface é marcado como interface de origem.
Representação de biblioteca de tipo
disinterface Class1Event {
properties:
methods:
[id(0x60020000)]
HRESULT Click();
};
coclass Class1
{
…
[default, source] Class1Event;
};
Consulte também
Conceitos
Conversão de Assembly exportados
Conversão do parâmetro exportado