Este artigo foi traduzido por máquina.

Tempo de Execução do Windows e o CLR

Nos bastidores com o .NET e o Tempo de Execução do Windows

Shawn Farkas

 

O tempo de execução do Windows (WinRT) fornece um conjunto grande de novas APIs para desenvolvedores de experiência do Windows. 4.5 O CLR, que navios como parte do Microsoft .NET Framework 4.5 no Windows 8, permite aos desenvolvedores escrever código para usar as APIs de forma natural, gerenciado apenas como se fossem outra biblioteca de classes. Você pode adicionar uma referência para o arquivo de metadados do Windows (WinMD) que define as APIs que você deseja chamar e chamá-los apenas como com um padrão API gerenciada. Visual Studio automaticamente adiciona uma referência para o built-in conjunto de APIs do WinRT para novos projetos de interface do usuário do Windows, assim seu aplicativo pode simplesmente começar a usar essa nova API.

Sob o capô, o CLR fornece a infra-estrutura para código gerenciado consumir arquivos WinMD e a transição entre código gerenciado e o tempo de execução do Windows. Neste artigo, vou mostrar alguns desses detalhes. Você vai sair com uma melhor compreensão do que ocorre nos bastidores, quando seu programa gerenciado chama a API do WinRT.

Consumindo WinMD arquivos de código gerenciado

WinRT APIs são definidos em arquivos de WinMD, que são codificados usando o formato de arquivo descrito no ECMA-335 (bit.ly/sLILI). Embora os arquivos WinMD e assemblies do .NET Framework compartilham uma codificação comum, eles não são o mesmo. Uma das principais diferenças nos metadados decorre do fato de que o sistema de tipos do WinRT é independente do sistema de tipo .NET.

Programas como o compilador c# e Visual Studio usam os metadados CLR APIs (como IMetaDataImport) para ler os metadados do assembly do .NET Framework e agora podem ler os metadados de arquivos de WinMD também. Porque os metadados não são exatamente o mesmo que um assembly do .NET, o leitor de metadados CLR insere um adaptador entre os metadados APIs e WinMD arquivo está sendo lido. Isso permite que os arquivos de WinMD ser lido como se fossem os assemblies do .NET (consulte Figura 1).


Figura 1 o CLR insere um adaptador de metadados entre arquivos de WinMD e a Interface pública de metadados

Executar ILDasm ajuda a compreender as modificações que o adaptador de metadados CLR executa em um arquivo de WinMD. Por padrão, o ILDasm mostra o conteúdo de um arquivo de WinMD em sua forma crua, como ela é codificada em disco sem o adaptador de metadados CLR. No entanto, se você passar o ILDasm o parâmetro de linha de comando/projeto, ele permite que o adaptador de metadados e você pode ver os metadados como o CLR e ferramentas gerenciadas vão lê-lo.

Executando cópias do ILDasm lado a lado — um com o parâmetro/projeto e sem — pode facilmente explorar as mudanças que o adaptador de metadados CLR faz para um arquivo de WinMD.

O tempo de execução do Windows e os sistemas de tipo .NET

Uma das principais operações que executa o adaptador de metadados é fundir os sistemas de tipo WinRT e .NET. De alto nível, cinco diferentes categorias de tipos de WinRT podem aparecer em um arquivo de WinMD e precisam ser considerados pelo CLR. Isso é listado na Figura 2. Vamos olhar para cada categoria em mais detalhes.

Figura 2 tipos de WinRT para um arquivo de WinMD

Category Exemplos
Tipos de WinRT padrão Windows.Foundation.Collections.PropertySet, Windows.Networking.Sockets.DatagramSocket
Tipos primitivos Byte, Int32, String, Object
Tipos previstos Windows.Foundation.Uri, Windows.Foundation.DateTime
Interfaces projetadas Windows.Foundation.Collections.IVector <T>, Windows.Foundation.Iclosable
Tipos com ajudantes de .NET Windows.Storage.Streams.IInputStream, Windows.Foundation.IasyncInfo

Tipos padrão do WinRT enquanto o CLR possui suporte especial para muitas categorias de tipos expostos pelo tempo de execução do Windows, a grande maioria dos tipos de WinRT não é tratada especialmente pelo CLR. Em vez disso, esses tipos aparecem para desenvolvedores .NET sem modificações, e podem ser usados como uma biblioteca de classes grandes para permitir escrever Windows Store aplicativos.

Tipos primitivos este conjunto de tipos primitivos é codificado em um arquivo de WinMD usando a mesma Enumeração ELEMENT_TYPE que uso de assemblies de .NET. O CLR automaticamente interpreta estes tipos primitivos, como se fossem os equivalentes do .NET.

Para a maior parte, tratando o WinRT tipos primitivos como tipos primitivos .NET apenas trabalha. Por exemplo, um inteiro de 32 bits tem o mesmo padrão de bits em tempo de execução do Windows como o faz no .NET, para que o CLR pode tratar um DWORD WinRT como um System. Int32 .NET sem nenhum problema. Mas duas exceções notáveis são seqüências de caracteres e objetos.

Em tempo de execução Windows, seqüências de caracteres são representadas com o tipo de dados HSTRING, que não é o mesmo como um System. String do .NET. Da mesma forma, ELEMENT_TYPE_OBJECT significa Object para .NET, enquanto que significa IInspectable * tempo de execução do Windows. Para seqüências de caracteres e objetos, o CLR precisa empacotar objetos em tempo de execução para converter entre as representações dos tipos WinRT e .NET. Você verá como este empacotamento funciona neste artigo.

Projetada tipos existem alguns tipos de .NET fundamentais existentes que têm equivalentes no sistema de tipo WinRT. Por exemplo, o tempo de execução do Windows define uma estrutura TimeSpan e uma classe de Uri, ambos os quais têm tipos correspondentes no .NET Framework.

Para evitar forçar os desenvolvedores do .NET para converter e para trás entre esses tipos de dados fundamentais, o CLR projetos a versão WinRT para seu equivalente do .NET. Essas projeções são efetivamente mesclar pontos que o CLR insere entre o .NET e o WinRT tipo de sistemas.

Por exemplo, a distribuição de tempo de execução do Windows­API de Client.RetrieveFeedAsync leva um WinRT Uri como seu parâmetro. Em vez de exigir desenvolvedores .NET criar manualmente uma nova instância de Windows.Foundation.Uri para passar para esta API, os projetos CLR tipo como um System. Uri, que permite que os desenvolvedores do .NET use o tipo eles estão mais familiarizados com.

Outro exemplo de uma projeção é o Windows.Founda­ção.Estrutura de HResult, que é projetada pelo CLR para o tipo de System. Exception. No .NET, os desenvolvedores acostumados a ver informações de erro transmitidas como uma exceção em vez de uma falha HRESULT, tendo assim uma API WinRT como IAsycn­Info.ErrorCode expressar informações de erro como uma estrutura de HResult não vai se sentir natural. Em vez disso, o CLR projetos HResult a exceção, o que torna uma API WinRT como IAsyncInfo.ErrorCode mais útil para desenvolvedores .NET. Aqui está um exemplo da Propriedade IAsyncInfo ErrorCode codificado em Windows.winmd:

.class interface public windowsruntime IAsyncInfo
{
  .method public abstract virtual
    instance valuetype Windows.Foundation.HResult
    get_ErrorCode()
}

E aqui está a Propriedade IAsyncInfo ErrorCode após a projeção de CLR:

 

.class interface public windowsruntime IAsyncInfo
{
 .method public abstract virtual
   instance class [System.Runtime]System.Exception
   get_ErrorCode()
}

Projetada Interfaces o tempo de execução do Windows também fornece um conjunto de interfaces fundamentais que têm equivalentes do .NET. O CLR executa projeções do tipo essas interfaces, bem como, novamente, mesclando os sistemas tipo esses pontos fundamentais.

Os exemplos mais comuns de interfaces projetadas são as interfaces de coleção WinRT, como IVector <T>, IIterable <T> e IMap < K, V >. Os desenvolvedores que usam o .NET estão familiarizados com interfaces de coleção como IList <T>, IEnumerable <T> e IDictionary < K, V >. Os projetos CLR WinRT coleção interfaces para seus equivalentes em .NET e também oculta o WinRT interfaces para que os desenvolvedores não têm de lidar com dois conjuntos funcionalmente equivalentes dos tipos que fazem a mesma coisa.

Além de projetar estes tipos quando eles aparecem como parâmetros e tipos de métodos de retorno, o CLR também deve projeto essas interfaces quando eles aparecem na lista de implementação de interface de um tipo. Por exemplo, o tipo do WinRT PropertySet implementa o WinRT IMap < string, object > interface. O CLR, no entanto, projetarão PropertySet como um tipo que implementa IDictionary < string, objeto >. Ao realizar essa projeção, os membros da PropertySet que são usados para implementar o IMap < string, object > estão escondidos. Em vez disso, os desenvolvedores do .NET acessar PropertySet através de correspondente IDictionary < string, object > métodos. Aqui está uma visão parcial do PropertySet como codificado em Windows.winmd:

.class public windowsruntime PropertySet
  implements IPropertySet,
    class IMap`2<string,object>,
    class IIterable`1<class IKeyValuePair`2<string,object> >
{
  .method public instance uint32 get_Size()
  {
    .override  method instance uint32 class 
      IMap`2<string,object>::get_Size()
  }
}

E aqui está uma visão parcial de PropertySet após a projeção de CLR:

.class public windowsruntime PropertySet
  implements IPropertySet,
    class IDictionary`2<string,object>,
    class IEnumerable`1<class KeyValuePair`2<string,object> >
{
  .method private instance uint32 get_Size()
  {
  }
}

Observe que ocorrem projeções de três tipos: IMap < string, object > a IDictionary < string, object >, IKeyValuePair < string, object > KeyValuePair < string, object > e IIterable <IKeyValuePair> para <KeyValuePair> de IEnumerable. Além disso, observe que o método de get_Size do IMap é escondido.

Tipos de .NET Framework ajudantes o tempo de execução do Windows tem vários tipos que não têm uma mesclagem completa ponto no sistema de tipo .NET, mas são importantes o suficiente para a maioria dos aplicativos que o .NET Framework fornece métodos auxiliares para trabalhar com eles. Dois dos melhores exemplos são as interfaces de fluxo e async WinRT.

Embora o CLR não projeto Windows.Storage.Streams.IRandomAccess­fluxo de System.Stream, ele fornece um conjunto de métodos de extensão para IRandom­AccessStream que permite que seu código tratar esses fluxos WinRT como se fossem riachos do .NET. Por exemplo, você pode facilmente ler um fluxo WinRT com .NET StreamReader, chamando o método de extensão OpenStreamForReadAsync.

O tempo de execução do Windows fornece um conjunto de interfaces que representam operações assíncronas, como a interface IAsyncInfo. O .NET Framework 4.5, há suporte interno para operações assíncronas, desenvolvedores que desejam usar com o WinRT APIs da mesma forma que eles fazem para APIs .NET a aguardar.

Para habilitar isso, o .NET Framework vem com um conjunto de métodos de extensão GetAwaiter para as interfaces de async WinRT. Esses métodos são usados pelo c# e Visual Basic compiladores para habilitar operações assíncronas de aguardando WinRT. Por exemplo:

private async Task<string> ReadFilesync(StorageFolder parentFolder, 
  string fileName)
{
  using (Stream stream = await parentFolder.OpenStreamForReadAsync(fileName))
  using (StreamReader reader = new StreamReader(stream))
  {
    return await reader.ReadToEndAsync();
    }
}

Transição entre o .NET Framework e Windows Runtime para o CLR fornece um mecanismo para código gerenciado perfeitamente chamar APIs WinRT e para o Runtime do Windows chamar código gerenciado.

Em seu nível mais baixo, o tempo de execução do Windows é construído em cima de conceitos COM, então não é nenhuma surpresa que o suporte a CLR chamado WinRT APIs é construído em cima de infra-estrutura interoperabilidade COM.

Uma diferença importante entre interoperabilidade WinRT e interoperabilidade é quanto menos configuração você tem que lidar com o tempo de execução do Windows. WinMD arquivos têm ricos metadados que descrevem todas os APIs que estão expondo com um mapeamento bem definido para o sistema de tipo .NET, então não há nenhuma necessidade de usar qualquer atributo MarshalAs em código gerenciado. Da mesma forma, porque o Windows 8 vem com arquivos de WinMD para seu WinRT APIs, você não precisa ter um assembly de interoperabilidade primário junto com seu aplicativo. Em vez disso, o CLR usa os arquivos de WinMD em caixa para descobrir tudo o que precisa saber sobre como chamar APIs do WinRT.

Esses arquivos de WinMD fornecem as definições de tipo gerenciado que são usadas em tempo de execução para permitir que desenvolvedores gerenciados acesso de execução do Windows. Embora as APIs que o CLR lê fora de um arquivo de WinMD contenham uma definição de método é formatada para ser facilmente usado em código gerenciado, a API subjacente do WinRT usa uma diferente assinatura API (por vezes referido como a interface binária de aplicação, ou ABI, assinatura). Um exemplo de diferença entre as assinaturas de API e ABI é que, como COM padrão, WinRT APIs retornar HRESULTS e o valor de retorno de uma API WinRT é na verdade um parâmetro de saída na assinatura do ABI. Eu vou mostrar um exemplo de como uma assinatura método gerenciado é transformada em uma assinatura WinRT ABI quando eu olhar para como o CLR chama a API do WinRT neste artigo.

Tempo de execução Callable Wrappers e COM Callable Wrappers

Quando um objeto WinRT entra o CLR, ele precisa ser chamado como se fosse um objeto .NET. Para fazer isso acontecer, o CLR encapsula cada objeto WinRT em um runtime callable wrapper (RCW). O RCW é que o código gerenciado interage com e é a interface entre o código e o WinRT objeto que seu código está usando.

Por outro lado, quando objetos gerenciados são usados desde o tempo de execução do Windows, eles precisam ser chamado como se fossem objetos WinRT. Neste caso, objetos gerenciados são empacotados em um COM callable wrapper (CCW) quando elas são enviadas para o tempo de execução do Windows. Porque o tempo de execução do Windows usa a mesma infra-estrutura como COM, ele pode interagir com CCWs a funcionalidade de acesso a objeto gerenciado (ver Figura 3).


Figura 3 usando Wrappers para tempo de execução do Windows e objetos gerenciados

Esboços sobre empacotamento

Quando código gerenciado transições entre qualquer limite de interoperabilidade, incluindo limites WinRT, várias coisas devem ocorrer:

  1. Converta gerenciados de parâmetros de entrada em WinRT equivalentes, incluindo a construção de CCWs para objetos gerenciados.
  2. Encontre a interface que implementa o WinRT método sendo chamado do RCW que o método está sendo chamado em.
  3. Chamar o método WinRT.
  4. Converta WinRT parâmetros de saída (incluindo valores de retorno) em gerenciado equivalentes.
  5. Converta qualquer falha HRESULTS da API do WinRT em uma exceção gerenciada.

Estas operações ocorrem em um esboço de empacotamento, que o CLR gera em nome do seu programa. Os stubs de empacotamento em um RCW são que o código gerenciado chama realmente antes em uma API WinRT. Da mesma forma, as chamadas de tempo de execução do Windows em stubs de empacotamento CLR gerado em um CCW quando ele passa em código gerenciado.

Esboços sobre empacotamento fornece a ponte que atravessa o fosso entre o tempo de execução do Windows e o .NET Framework. Entender como eles funcionam irá ajudá-lo a ganhar uma compreensão mais profunda do que acontece quando seu programa chama em tempo de execução do Windows.

Uma chamada de exemplo

Imagine uma API do WinRT que leva a uma lista de seqüências de caracteres e concatena-los, com uma seqüência de caracteres de separador entre cada elemento. Essa API pode ter uma assinatura gerenciada, tais como:

public string Join(IEnumerable<string> list, string separator)

O CLR deve chamar o método, como é definido na ABI, então ele precisa descobrir a assinatura ABI do método. Felizmente, um conjunto de transformações determinísticas pode ser aplicado para obter inequivocamente uma assinatura ABI dada uma assinatura de API. A primeira transformação é substituir os tipos de dados projetado com seus equivalentes do WinRT, que retorna a API para a forma em que é definido no arquivo WinMD antes que o adaptador de metadados carregado. Neste caso, IEnumerable <T> é realmente uma projeção de IIterable <T>, portanto, a WinMD esta função é realmente:

public string Join(IIterable<string> list, string separator)

WinRT seqüências de caracteres são armazenadas em um tipo de dados HSTRING, então para esta função, o tempo de execução do Windows, na verdade, parece que:

public HSTRING Join(IIterable<HSTRING> list, HSTRING separator)

Na camada de ABI, onde a chamada realmente ocorre, WinRT APIs tem HRESULT valores de retorno e o valor de retorno de sua assinatura é um parâmetro de saída. Além disso, os objetos são ponteiros, então seria a assinatura ABI para este método:

HRESULT Join(__in IIterable<HSTRING>* list, HSTRING separator, __out HSTRING* retval)

Todos os métodos do WinRT devem ser parte de uma interface que implementa um objeto. Nosso método de junção, por exemplo, pode ser parte de uma interface IConcatenation, suportada por uma classe de StringUtilities. Antes de fazer um método chamar Join, o CLR deve obter um porão do ponteiro de interface IConcatenation para fazer a chamada em.

O trabalho de um esboço de empacotamento é para converter do original gerenciado chamar em um RCW para a chamada WinRT final em uma interface WinRT. Neste caso, o pseudocódigo para o stub empacotamento pode parecer Figura 4 (com limpeza chamadas omitidas para clareza).

Figura 4 exemplo de um esboço de empacotamento para fazer uma chamada do CLR para o tempo de execução do Windows

public string Join(IEnumerable<string> list, string separator)
{
  // Convert the managed parameters to WinRT types
  CCW ccwList = GetCCW(list);
  IIterable<HSTRING>* pCcwIterable = ccwList.QueryInterface(IID_IIterable_HSTRING);
  HSTRING hstringSeparator = StringToHString(separator);
  // The object that managed code calls is actually an RCW
  RCW rcw = this;
  // You need to find the WinRT interface pointer for IConcatenation
  // implemented by the RCW in order to call its Join method
  IConcatination* pConcat = null;
  HRESULT hrQI = rcw.QueryInterface(IID_ IConcatenation, out pConcat);
  if (FAILED(hrQI))
    {
      // Most frequently this is an InvalidCastException due to the WinRT
      // object returning E_NOINTERFACE for the interface that contains
      // the method you're trying to call
      Exception qiError = GetExceptionForHR(hrQI);
      throw qiError;
    }
    // Call the real Join method
    HSTRING returnValue;
    HRESULT hrCall = pConcat->Join(pCcwIterable, hstringSeparator, &returnValue);
    // If the WinRT method fails, convert that failure to an exception
    if (FAILED(hrCall))
    {
      Exception callError = GetExceptionForHR(hrCall);
      throw callError;
    }
    // Convert the output parameters from WinRT types to .NET types
    return HStringToString(returnValue);
}

Neste exemplo, o primeiro passo é converter os parâmetros gerenciados de sua representação gerenciada para sua representação WinRT. Neste caso, o código cria um CCW para o parâmetro lista e converte o parâmetro System para um HSTRING.

O próximo passo é encontrar o WinRT interface que fornece a implementação de junção. Isso ocorre por emitir uma chamada QueryInterface para o WinRT objeto é empacotado por RCW que o código gerenciado chamado participar. A razão mais comum que um InvalidCastException fica jogado de uma chamada de método WinRT é se essa chamada QueryInterface falha. Uma razão que isso pode acontecer é que o WinRT objeto não implementa todas as interfaces que o chamador espera-lo.

Agora ocorre a ação real — o esboço de interoperabilidade faz a chamada para o método WinRT Join, proporcionando um local para que possa armazenar a lógica retornar valor HSTRING. Se o método WinRT falhar, ele indica que esta com uma falha HRESULT, que o esboço de interoperabilidade converte uma exceção e lança. Isto significa que se seu código gerenciado vê uma exceção ser lançada a partir de uma chamada de método WinRT, é provável que o WinRT método sendo chamado retornou uma falha HRESULT e o CLR emitiu uma exceção para indicar o estado falha em seu código.

O último passo é converter os parâmetros de saída de sua representação do WinRT para sua forma de .NET. Neste exemplo, o lógico retorna valor é um parâmetro de saída da junção chamada e precisa ser convertido de um HSTRING para um String do .NET. Esse valor pode ser retornado, em seguida, como resultado de stub.

Chamada de Windows Runtime em código gerenciado

Chamadas que originam o Runtime do Windows e destino gerenciado código de trabalho de maneira semelhante. O CLR responde a chamadas de QueryInterface que o componente de tempo de execução do Windows faz contra ele com uma interface que possui uma tabela de função virtual que é preenchida com métodos de interoperabilidade do esboço. Estes Esboços sobre executar a mesma função que o que mostrei anteriormente, mas no sentido inverso.

Vamos considerar o caso da API se juntar novamente, exceto que desta vez assumir ele é implementado no código gerenciado e está sendo chamado em de um componente de tempo de execução do Windows. Pseudocódigo para um esboço que permite que essa transição ocorra pode parecer Figura 5.

Figura 5 exemplo de um esboço de empacotamento para fazer uma chamada de tempo de execução do Windows para o CLR

HRESULT Join(__in IIterable<HSTRING>* list, 
  HSTRING separator, __out HSTRING* retval)
{
  *retval = null;
  // The object that native code is calling is actually a CCW
  CCW ccw = GetCCWFromComPointer(this);
  // Convert the WinRT parameters to managed types
  RCW rcwList = GetRCW(list);
  IEnumerable<string> managedList = (IEnumerable<string>)rcwList;
  string managedSeparator = HStringToString(separator);
  string result;
  try
  {
    // Call the managed Join implementation
    result = ccw.Join(managedList, managedSeparator);
  }
  catch (Exception e)
  {
    // The managed implementation threw an exception -
    // return that as a failure HRESULT
    return GetHRForException(e);
  }
  // Convert the output value from a managed type to a WinRT type
  *retval = StringToHSTring(result);
  return S_OK;
}

Em primeiro lugar, esse código converte os parâmetros de entrada de seus tipos de dados WinRT em tipos gerenciados. Supondo que a lista de entrada é um objeto WinRT, o esboço deve obter um RCW para representar esse objeto para permitir que o código gerenciado para usá-lo. O valor de seqüência de caracteres é simplesmente convertido de um HSTRING de um System. String.

Em seguida, a chamada é feita para o gerenciado implementação do método Join na para a esquerda. Se esse método lança uma exceção, o esboço de interoperabilidade captura-lo e converte-lo para uma falha HRESULT retornado ao chamador WinRT. Isso explica por que algumas exceções descartadas a partir de código gerenciado, chamado pelos componentes de tempo de execução do Windows não falhar o processo. Se o componente de tempo de execução do Windows manipula a falha HRESULT, que é efetivamente o mesmo como captura e manipulação de exceção gerada.

O último passo é converter o parâmetro de saída de seu tipo de dados do .NET para o tipo de dados WinRT equivalente, neste caso, convertendo o System para um HSTRING. O valor de retorno é então colocado em um sucesso que HRESULT retornado e o parâmetro de saída.

Interfaces projetadas

Anteriormente, mencionei que o CLR irá projeto algumas interfaces WinRT em interfaces equivalentes do .NET. Por exemplo, IMap < K, V > é projetada para IDictionary < K, V >. Isso significa que qualquer mapa WinRT está acessível como um dicionário de .NET e vice-versa. Para habilitar essa projeção para o trabalho, um outro conjunto de stubs é necessária para implementar a interface WinRT em termos de interface do .NET, projeta-se para e vice-versa. Por exemplo, IDictionary < K, V > tem um método TryGetValue, mas IMap < K, V > não contém esse método. Para permitir que chamadores gerenciados usar TryGetValue, o CLR fornece um esboço que implementa este método em termos de métodos que possuem IMap. Isto pode parecer semelhante ao Figura 6.

Figura 6 implementação conceitual de IDictionary em termos de IMap

bool TryGetValue(K key, out V value)
{
  // "this" is the IMap RCW
  IMap<K,V> rcw = this;
  // IMap provides a HasKey and Lookup function, so you can
  // implement TryGetValue in terms of those functions
  if (!rcw.HasKey(key))
    return false;
  value = rcw.Lookup(key);
  return true;
}

Observe que para fazer o seu trabalho, este esboço de conversão faz várias chamadas para a implementação subjacente do IMap. Por exemplo, digamos que você escreveu o seguinte trecho de código gerenciado para ver se um objeto Windows.Foundation.Collections.PropertySet contém a chave "NYJ":

 

object value;
if (propertySet.TryGetValue("NYJ", out value))
{
  // ...
}

Como a chamada TryGetValue determina se o conjunto de propriedades contém a chave, a pilha de chamada pode parecer Figura 7.

Figura 7 a pilha de chamada para chamada TryGetValue

Stack Description
PropertySet::HasKey Implementação do WinRT PropertySet
HasKey_Stub Empacotamento esboço converter chamada de HasKey do esboço de dicionário em uma chamada WinRT
TryGetValue_Stub Stub implementação IDictionary em termos de IMap
aplicativo Gerenciado de código do aplicativo chamando PropertySet.TryGetValue

Conclusão

O suporte CLR para o Runtime do Windows permite que os desenvolvedores gerenciados chamar APIs WinRT definidos em arquivos de WinMD tão facilmente como eles podem chamar APIs gerenciadas definidos em um assembly do .NET padrão. Sob o capô, o CLR usa um adaptador de metadados para realizar projeções que ajudam a mesclar o WinRT tipo sistema com o sistema de tipo .NET. Ele também usa um conjunto de stubs de interoperabilidade para permitir código .NET chamar os métodos do WinRT e vice-versa. Juntas, estas técnicas torná-lo fácil para os desenvolvedores gerenciados chamar APIs do WinRT de seus aplicativos Windows Store.

Shawn Farkas tem trabalhado no CLR para 10 anos e é atualmente o líder de desenvolvimento responsável pela projeção de tempo de execução CLR Windows e interoperabilidade .NET. Antes do Microsoft .NET Framework 4.5, trabalhou sobre o modelo de segurança do CLR. Seu blog pode ser encontrado em blogs.msdn.com/shawnfa.

Agradecemos aos seguintes especialistas técnicos pela revisão deste artigo: Ryan Byington, Layla Driscoll e Yi Zhang