Eksportuj (0) Drukuj
Rozwiń wszystko
EN
Ta zawartość nie jest dostępna w wymaganym języku. Wersja w języku angielskim znajduje się tutaj.

Best Practices for Running Unmanaged Code in Azure Applications

Updated: June 19, 2014

Writing .NET code for Azure applications is for the most part just like writing .NET code for Windows applications. There are subtle differences to be aware of when writing .NET code for one platform versus the other. This document provides recommendations for running unmanaged/native code in Azure Applications.

Authors Christian Martinez, Trace Young, and Mark Simms

Best Practices for Running Native Code from Azure Applications

The following sections provide recommendations for ensuring that native code runs correctly when developing Azure applications that call native code.

Verify that the Native Code you deploy with your Azure Application is Compiled in Release Mode

To configure native code to compile in Release mode right-click on the native code project, select Properties to display the Properties page, and select the Release configuration option available from the Build tab of the Properties page:

Project Properties Release Mode Build Option

noteNote
Runtime errors stating that you are missing DLLs, such as msvcr100d.dll or msvcp100d.dll, indicate that the native code you deployed was compiled in Debug mode. The files msvcr100d.dll and msvcp100d.dll are not redistributable DLLs. For more information about determining which C++ DLL files to redistribute see Determining Which DLLs to Redistribute (http://go.microsoft.com/fwlink/p/?LinkId=236016.)

Ensure that Native Code can be Located by your Azure Application when Running in Azure Compute Emulator

Follow these steps to ensure that your Azure Application can locate any referenced native code when running in Azure Compute Emulator:

  1. Set Appropriate Properties for Compiled Native Code Files in Visual Studio

    Include the compiled native code file as a project item and on the Properties dialog for the file set the Copy to Output Directory option to Copy always and the Build Action option to None.

    This will copy the compiled native code file into the \bin directory and ensure that your Azure Application can locate the compiled native code file when running in Azure Compute Emulator.



    Unmanaged Code Build Actions Dialog Box
  2. When troubleshooting your RoleEntry implementation in the Azure Compute Emulator it can make it easier to debug issues if you copy the Compiled Native Code File to the devfabric runtime directory

    • For example, when using Azure SDK version 1.5 or earlier copy the compiled native code file to the following directory:


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


    • Or, when using Azure SDK version 1.6 or later copy the compiled native code file to this directory:


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

  3. Ensure that Azure Applications Running in a Web Role Instance can Locate any Referenced Native Code

    If an Azure Application references native code that is wrapped using C++/CLI and the Azure Application is running in a Web Role instance, use one of the following methods to ensure that the Azure Application can locate the referenced native code:



    noteNote
    The steps below reference the CppCliWebRole project provided with the sample code in PinvokeCppCliInAzure.zip, available for download at http://azureunmanagedcode.codeplex.com/. For more information about the sample code see Sample Code: Running Native Code from Azure Applications.

    Method 1: Edit the PATH Environment Variable, then Restart Azure Compute Emulator and IIS:

    1. Stop and exit Azure Compute Emulator.

    2. Edit your PATH environment variable to point to a directory containing the native compiled code.

    3. Type iisreset from an elevated command prompt.

    4. Press F5 to run the sample code.

    Method 2: Use a startup command

    In the steps below, the native code is in the file ExampleNativeCode.dll.

    1. Stop and exit Azure Compute Emulator.

    2. Open the indist.cmd file included with the CppCliWebRole project.

    3. Change the following line:

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



      copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
    4. Save the project.

    5. Press F5 to run the sample code.

    noteNote
    The use of a startup command works for actual deployments as well. If you prefer avoiding references to the IIS system directory then you might alternatively create and run a script to:

    1. Change the PATH environment variable to point to the directory containing the native compiled code.

    2. Restart IIS and any processes that depend on it.

Ensure that the Compiled Native Code is 64-bit

Azure is a 64-bit platform, as are the Azure application (worker and web role) hosts. If you are not using a pure 64-bit development environment and your application references native code, your application will throw errors. One simple test to verify that all of the native code you are referencing is 64-bit is by testing the native code using console test applications that are hard coded to run as 64 bit applications.

Use the Native Multi-targeting Feature of Visual Studio to Build Native Libraries with Visual Studio 2008 Platform Toolset

By default, only the Visual C++ runtime libraries for Visual C++ 2008 are installed on Azure worker and web roles. Therefore, native code compiled against the Visual C++ runtime library for other versions of Visual C++ will fail to load in worker and web role instances. If you have both Visual Studio 2008 and a later version installed on the same computer you can use the native multi-targeting feature of Visual Studio to build native libraries for your application with the Visual Studio 2008 platform toolset (compiler, linker, headers, and libraries). For more information about using Visual Studio to build an application with the Visual Studio 2008 platform toolset see How to: Modify the Target Framework and Platform Toolset(http://go.microsoft.com/fwlink/?LinkId=324964).

Add an Elevated Startup Task to your Worker or Web Role Project to Install the Native Visual C++ Libraries for Visual C++ on Worker/Web Role Instances

You can add an elevated startup task to your worker or web role project to copy and install the required version of the runtime libraries. The following steps describe how to create an elevated startup task to copy the 64-bit version of the Microsoft Visual C++ 2010 Redistributable Package to a worker / web role and run the redistributable package to install the Visual C++ libraries for Visual C++ 2010 onto the worker / web role instances. Other versions of Visual C++ will require a distributable package specific to that version:

  1. Create a Startup folder for your worker or web role project.

  2. Copy vcredist_x64.exe (http://go.microsoft.com/fwlink/p/?LinkId=225987) to the Startup folder.

  3. Create a startup.cmd file in the Startup folder.

  4. Edit startup.cmd and add the following line:


    "%~dps0vcredist_x64.exe" /q /norestart


  5. Modify the properties of vcredit_x64.exe and startup.cmd from Visual Studio Solution Explorer. Set the Build Action option to Content and the Copy to Output Directory option to Copy if Newer.

  6. Edit the ServiceDefinition.csdef file for the role by adding the following elevated startup task to execute startup.cmd:


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

Use Process Monitor to Troubleshoot Problems Loading Files in Azure Compute Emulator

The error message generated when an assembly cannot be loaded by Azure Computer Emulator may be non-intuitive. To troubleshoot problems loading files in a Worker or Web Role host instance use Process Monitor as follows:

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

  2. Launch Process Monitor to troubleshoot problems with Azure Applications loading files when running in Azure Compute Emulator.

  3. Set filter parameters as depicted below for the Azure Compute Emulator host. If troubleshooting problems with Azure Applications running in a worker role project change the filter to display entries with the process name WaWorkerHost.exe rather than WaWebHost.exe.



    Screenshot of Process Explorer



  4. Look for any NAME_NOT_FOUND messages. This will help to isolate the missing library file. Once you have determined which file is missing you can narrow the scope of the search by applying a filter to isolate only messages related to that file.

Configure Worker/Web Roles with the .NET Full Trust Level

To enable Azure applications to execute 64-bit native code using P/Invoke, first configure the associated worker or web roles with the .NET Full Trust level. For more information about calling native code from applications running in Azure worker or web roles see the following resources:

Sample Code: Running Native Code from Azure Applications

This section describes the sample code in PinvokeCppCliInAzure.zip (http://go.microsoft.com/fwlink/p/?LinkId=236170), available for download at http://azureunmanagedcode.codeplex.com/

noteNote
When using Azure Compute Emulator from Visual Studio to work through the sample code, it is not necessary to run the portion of the startup command that installs the Visual C++ runtime libraries, therefore you should comment out the following line in the startup.cmd file:

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

The sample code contains a project which creates a native DLL called ExampleNativeCode.dll. It has been compiled as a 64 bit library in Release mode as recommended.

noteNote
Exit and restart Azure Compute Emulator each time you run any of the sample code if any changes are made to the code or to Windows environment variables. This will ensure that any referenced native code is released from memory so that it can be recompiled and that any environment variable changes are picked up by Azure Compute Emulator the next time it runs.

The sample code ExampleNativeCode.dll is wrapped using P/Invoke in a project called ManagedUsingPinvoke and wrapped using C++/CLI in a project called ManagedUsingCppCLI.

The code in the native DLL is a modified version of the default Win32 project template with exports and contains a single function that answers all known questions in the universe, as long as the answer for said questions is the number 42:

EXAMPLENATIVECODE_API int fnExampleNativeCode(void)
{
    return 42;
}

The P/Invoke code and the C++/CLI code that utilize this function are very similar:

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();
    }
};

Both Worker Role samples (PInvokeWorkerRole and CppCliWorkerRole) in the solution invoke the code in the same manner:

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

Both Worker Role samples include the native compiled code and are configured to always copy the native compiled code to the output directory.

When you run press F5 to execute the code in Azure Compute Emulator you should see the following output:

Sample Code Console Output

Certain considerations apply when calling native code from Azure Applications running in a Web Role instance as compared to running in a Worker Role instance. The PInvokeWebRole and CppCliWebRole projects contain the following code in a slightly modified version of the default ASP.NET project template:

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>

Running the PInvokeWebRole project will result in the expected output similar to the following:

PInvoke console output from native code

However, running the CppCliWebRole project without modification will result in the following error:

Error message returned by web role
noteNote
This error occurs even with the proper project settings applied to copy the native compiled code to the output directory.

To address this error, use one of the methods described in Ensure that Azure Applications Running in a Web Role Instance can Locate any Referenced Native Code. After using one of these methods you should see the expected output for the CppCliWebRole page, similar to the following:

C++/CLI console output from native code

Zawartość społeczności

Dodaj
Pokaż:
© 2014 Microsoft