Exportar (0) Imprimir
Expandir Tudo

Práticas recomendadas para executar código não gerenciado em aplicativos do Azure

Atualizado: junho de 2014

Gravar código .NET para aplicativos do Azure é geralmente similar a gravar código .NET para aplicativos do Windows. Há diferenças sutis que devem ser consideradas para gravar o código .NET para uma plataforma em relação à outra. Este documento fornece recomendações para executar código não gerenciado/nativo em aplicativos do Azure.

Autores: Christian Martinez, Trace Young e Mark Simms

As seções a seguir fornecem recomendações para garantir que o código nativo seja executado corretamente ao desenvolver aplicativos do Azure que chamam o código nativo.

Para configurar o código nativo para compilar no modo de liberação, clique com o botão direito do mouse no projeto de código nativo, selecione Propriedades ver a página Propriedades e selecione a opção de configuração Lançamento disponível na guia Compilação da página Propriedades:

Opção de construção do modo de liberação das propriedades do projeto

noteObservação
Os erros em tempo de execução informando que você não tem DLLs, como msvcr100d.dll ou msvcp100d.dll, indicam que o código nativo implantado foi compilado no modo de depuração. Os arquivos msvcr100d.dll e msvcp100d.dll não são DLLs redistribuíveis. Para obter mais informações sobre como determinar quais arquivos DLL C++ devem ser redistribuídos, consulte Determinando quais DLLs devem ser redistribuídas (http://go.microsoft.com/fwlink/p/?LinkId=236016).

Siga estas etapas para verificar se seu aplicativo do Azure pode localizar qualquer código nativo referido quando executado no emulador de computação do Azure:

  1. Definir as propriedades adequadas para arquivos de códigos nativos compilados no Visual Studio

    Inclua o arquivo de código nativo compilado como item de projeto e, na caixa de diálogo Propriedades do arquivo, defina a opção Copiar para Diretório de Saída como Copiar sempre e a opção Ação de Compilação como Nenhuma.

    Isso copiará o arquivo de código nativo compilado no diretório \bin e verificará se seu aplicativo do Azure pode localizar o arquivo de código nativo compilado quando executado no emulador de computação do Azure.



    Caixa de diálogo Ações de Construção de Código Não Gerenciado
  2. Para solucionar problemas de sua implementação de RoleEntry no emulador de computação do Azure, pode ser mais fácil depurar os problemas se você copiar o arquivo de código nativo compilado no diretório de tempo de execução devfabric.

    • Por exemplo, usando o Azure SDK versão 1.5 ou anterior, copie o arquivo de código nativo compilado no seguinte diretório:


      C:\Program Files\Azure SDK\[SDK Version]\bin\devfabric\x64\


    • Ou, usando o Azure SDK versão 1.6 ou posterior, copie o arquivo de código nativo compilado neste diretório:


      C:\Program Files\Azure SDK\[SDK Version]\bin\runtimes\base\x64\

  3. Verificar se os aplicativos do Azure executados em uma instância de função da Web podem localizar qualquer código nativo referenciado

    Se um aplicativo do Azure referencia o código nativo encapsulado usando C++/CLI e o aplicativo do Azure estiver em execução em uma instância de função da Web, use um dos seguintes métodos para verificar se o aplicativo do Azure pode localizar o código nativo referenciado:



    noteObservação
    As etapas abaixo fazem referência ao projeto CppCliWebRole fornecido com o código de exemplo em PinvokeCppCliInAzure.zip, disponível para download em http://azureunmanagedcode.codeplex.com/. Para obter mais informações sobre o código da amostra, consulte: Código do exemplo: executando código nativo em aplicativos do Azure.

    Método 1: editar a variável de ambiente PATH, reiniciar o emulador de computação do Azure e o IIS:

    1. Interrompa e saia do emulador de computação do Azure.

    2. Editar sua variável de ambiente PATH para apontar para um diretório que contém o código nativo compilado.

    3. Digite iisreset em um prompt de comando elevado.

    4. Pressione F5 para executar o código de exemplo.

    Método 2: usar um comando de inicialização

    Nas etapas abaixo, o código nativo está no arquivo ExampleNativeCode.dll.

    1. Interrompa e saia do emulador de computação do Azure.

    2. Abra o arquivo indist.cmd incluído no projeto CppCliWebRole.

    3. Altere a seguinte linha:

      REM copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
      Para:



      copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
    4. Salve o projeto.

    5. Pressione F5 para executar o código de exemplo.

    noteObservação
    O uso de um comando de inicialização funciona para implantações reais também. Se você preferir evitar referências ao diretório do sistema IIS, também pode criar e executar um script para:

    1. Alterar a variável de ambiente PATH para apontar para o diretório que contém o código nativo compilado.

    2. Reinicie o IIS e os processos que dependem dele.

O Azure é uma plataforma de 64 bits, assim como os hosts de aplicativo do Azure (função de trabalho e da Web). Se você não estiver usando um ambiente de desenvolvimento puro de 64 bits e seu aplicativo referenciar o código nativo, seu aplicativo gerará erros. Um teste simples para verificar se todo o código nativo que você está referenciando é de 64 bits é testar o código nativo usando aplicativos de teste de console codificados para executar aplicativos de 64 bits.

Por padrão, somente as bibliotecas de tempo de execução do Visual C++ para Visual C++ 2008 são instaladas em funções de trabalho e da Web do Azure. Portanto, o código nativo compilado na biblioteca de tempo de execução do Visual C++ para outras versões do Visual C++ não carregará em instâncias de função de trabalho e da Web. Se você tiver o Visual Studio 2008 e uma versão posterior instalados no mesmo computador, poderá usar o recurso de vários destinos nativos do Visual Studio para criar bibliotecas nativas para o aplicativo com o conjunto de ferramentas da plataforma do Visual Studio 2008 (compilador, vinculador, cabeçalhos e bibliotecas). Para obter mais informações sobre como usar o Visual Studio para criar um aplicativo com o conjunto de ferramentas da plataforma Visual Studio 2008 consulte Como: Modificar a estrutura de destino e o conjunto das ferramentas da plataforma (http://go.microsoft.com/fwlink/?LinkId=324964).

Você pode adicionar uma tarefa de inicialização elevada ao projeto da função de trabalho ou da Web para copiar e instalar a versão exigida das bibliotecas de tempo de execução. As etapas a seguir descrevem como criar uma tarefa de inicialização elevada para copiar a versão de 64 bits do pacote redistribuível do Microsoft Visual C++ 2010 em uma função de trabalho/da Web e executar o pacote redistribuível para instalar as bibliotecas do Visual C++ para o Visual C++ 2010 nas instâncias de função de trabalho/da Web. Outras versões do Visual C++ exigirão um pacote distribuível específico dessa versão:

  1. Crie uma pasta Inicialização para seu projeto de função de trabalho ou da Web.

  2. Copie vcredist_x64.exe (http://go.microsoft.com/fwlink/p/?LinkId=225987) na pasta Inicialização.

  3. Crie um arquivo startup.cmd na pasta Inicialização.

  4. Edite startup.cmd e adicione a seguinte linha:


    "%~dps0vcredist_x64.exe" /q /norestart


  5. Modifique as propriedades de vcredit_x64.exe e de startup.cmd no Gerenciador de Soluções do Visual Studio. Defina a opção Ação de Compilação como Conteúdo e a opção Copiar para Diretório de Saída como Copiar se mais recente.

  6. Edite o arquivo ServiceDefinition.csdef para a função adicionando a seguinte tarefa de inicialização elevada para executar startup.cmd:


    < Task commandLine ="Startup\Startup.cmd" executionContext ="elevated" taskType ="simple" />

A mensagem de erro gerada quando um assembly não pode ser carregado pelo emulador de computação do Azure pode não ser intuitiva. Para solucionar problemas de carregamento de arquivos em uma instância host de função de trabalho ou da Web, use o Process Monitor da seguinte forma:

  1. Baixe o Process Monitor do Process Monitor v2.96 (http://go.microsoft.com/fwlink/p/?LinkID=137175).

  2. Inicie o Process Monitor para solucionar problemas de carregamento de arquivos por aplicativos do Azure em execução no emulador de computação do Azure.

  3. Configure os parâmetros de filtragem conforme descrito abaixo para o host do emulador de computação do Azure. Quando for solucionar problemas com aplicativos do Azure executados em um projeto de função de trabalho, altere o filtro para exibir entradas com o nome de processo WaWorkerHost.exe em vez de WaWebHost.exe.



    Captura de tela da guia Explorador de Processos



  4. Procure as mensagens de NAME_NOT_FOUND. Isso ajudará a isolar o arquivo de biblioteca que está faltando. Uma vez determinado o arquivo que está faltando, você pode restringir o escopo da pesquisa aplicando um filtro para isolar somente as mensagens relacionadas a esse arquivo.

Para permitir que aplicativos do Azure executem código nativo de 64 bits com P/Invoke, configure primeiramente as funções de trabalho ou da Web associadas ao nível de confiança total do .NET. Para obter mais informações sobre como chamar código nativo de aplicativos em execução em funções de trabalho ou da Web do Azure, consulte os seguintes recursos:

Esta seção descreve o código de exemplo em PinvokeCppCliInAzure.zip (http://go.microsoft.com/fwlink/p/?LinkId=236170), disponível para download em http://azureunmanagedcode.codeplex.com/

noteObservação
Quando o emulador de computação do Azure no Visual Studio é usado para trabalhar com o código de exemplo, não é necessário executar a parte do comando de inicialização que instala as bibliotecas de tempo de execução do Visual C++ e, portanto, você deve comentar a seguinte linha no arquivo startup.cmd:

REM "%~dps0vcredist_x64.exe" /q /norestart

O código de exemplo contém um projeto que cria uma DLL nativa chamada ExampleNativeCode.dll. Ele foi compilado como uma biblioteca de 64 bits no modo de versão, conforme recomendado.

noteObservação
Saia e reinicie o emulador de computação do Azure sempre que executar um código de exemplo se alguma alteração for feita no código ou nas variáveis de ambiente do Windows. Isso garantirá que todo código nativo referenciado seja liberado da memória para que possa ser recompilado e que qualquer alteração da variável de ambiente seja detectada pelo emulador de computação do Azure na próxima vez em que ele for executado.

O código de exemplo ExampleNativeCode.dll é encapsulado usando P/Invoke em um projeto chamado ManagedUsingPinvoke e encapsulado usando C++/CLI em um projeto chamado ManagedUsingCppCLI.

O código na DLL nativa é uma versão modificada do modelo de projeto padrão do Win32 com exportações e contém uma única função que responde todas as perguntas conhecidas no universo, contanto que a resposta para as ditas perguntas seja o número 42:

EXAMPLENATIVECODE_API int fnExampleNativeCode(void)
{
    return 42;
}

Os códigos P/Invoke e C++/CLI que utilizam essa função são muito semelhantes:

P/Invoke

public class Class1
{
    [DllImport("ExampleNativeCode.dll")]
    static extern int fnExampleNativeCode();

    public int GetTheAnswerToEverything()
    {
        return fnExampleNativeCode();
    }
}

C++/CLI

public ref class Class1
{
public:

    int GetTheAnswerToEverything()
    {
        return fnExampleNativeCode();
    }
};

Os dois exemplos de função de trabalho (PInvokeWorkerRole e CppCliWorkerRole) na solução chamam o código da mesma maneira:

try
{
    Trace.WriteLine(new Class1().GetTheAnswerToEverything());
}
catch (Exception ex)
{
    Trace.WriteLine(ex);
}

Os dois exemplos de função de trabalho incluem o código nativo compilado e são configurados para copiar sempre o código nativo compilado no diretório de saída.

Quando for executar, pressione F5 para executar o código no emulador de computação do Azure. Você deverá ver o seguinte resultado:

Saída de console de código de amostra

Algumas considerações se aplicam à chamada de código nativo em aplicativos do Azure executados em uma instância de função da Web em relação à execução em uma instância de função de trabalho. Os projetos PInvokeWebRole e CppCliWebRole contêm o seguinte código em uma versão ligeiramente modificada do modelo de projeto padrão do ASP.NET:

P/Invoke

<p>
    This is PInvoke <br />
        <%=Environment.GetEnvironmentVariable("PATH") %> <br />
        <%=new Class1().GetTheAnswerToEverything() %>
</p>

C++/CLI

<p>
    This is C++/CLI <br />
        <%=Environment.GetEnvironmentVariable("PATH") %> <br />
        <%=new Class1().GetTheAnswerToEverything() %>
</p>

Executar o projeto PInvokeWebRole resultará no resultado esperado semelhante ao seguinte:

Saída de console PInvoke de código nativo

No entanto, executar o projeto CppCliWebRole sem modificação resultará no seguinte erro:

Mensagem do erro retornada por função web
noteObservação
Esse erro ocorre mesmo com as configurações corretas de projeto aplicadas para copiar o código nativo compilado no diretório de saída.

Para corrigir esse erro, use um dos métodos descritos em Ensure that Azure Applications Running in a Web Role Instance can Locate any Referenced Native Code . Depois de usar um destes métodos, você deverá ver o resultado esperado para a página CppCliWebRole, semelhante ao seguinte:

Saída de console C++/CLI de código nativo

Mostrar:
© 2015 Microsoft