Экспорт (0) Печать
Развернуть все

Рекомендации по выполнению неуправляемого кода в приложениях Azure

Обновлено: Июнь 2014 г.

Написание кода .NET для приложений Azure по большей части аналогично написанию кода .NET для приложений Windows. Существуют небольшие отличия, которые нужно учитывать при написании кода .NET для той или иной платформы. В этом документе представлены рекомендации по выполнению неуправляемого или собственного кода в приложениях Azure.

Авторы Кристиан Мартинез (Christian Martinez), Трейс Янг (Trace Young) и Марк Симмс (Mark Simms)

В следующих разделах представлены рекомендации по обеспечению правильной работы машинного кода при разработке приложений Azure, которые вызывают машинный код.

Для настройки компиляции машинного кода в режиме выпуска щелкните проект неуправляемого кода правой кнопкой, выберите Свойства, чтобы открыть страницу Свойства, а затем выберите параметр конфигурации Выпуск на вкладке Построение страницы свойств.

noteПримечание
Ошибки времени выполнения, указывающие на отсутствие таких DLL-файлов, как msvcr100d.dll или msvcp100d.dll, означают, что развернутый машинный код был скомпилирован в режиме отладки. Файлы msvcr100d.dll и msvcp100d.dll не являются распространяемыми DLL-библиотеками. Дополнительные сведения о том, как определить, какие DLL-файлы C++ следует распространять, см. в статье Определение библиотек DLL для распространения (http://go.microsoft.com/fwlink/p/?LinkId=236016).

Выполните эти действия, чтобы убедиться, что ваше приложение Azure может найти любой указанный машинный код при выполнении в эмуляторе вычислений Azure.

  1. Установка необходимых свойств для файлов скомпилированного машинного кода в Visual Studio

    Добавьте файл скомпилированного машинного кода как элемент проекта, а в диалоговом окне Свойства файла задайте для параметра Копировать в выходной каталог значение Всегда копировать, а для параметра Действие построения выберите Нет.

    Файл скомпилированного машинного кода при этом будет скопирован в каталог \bin, после чего необходимо убедиться, что ваше приложение Azure может найти этот файл при выполнении в эмуляторе вычислений Azure.



  2. При устранении неполадок реализации RoleEntry в эмуляторе вычислений Azure можно упростить отладку ошибок, скопировав файл скомпилированного машинного кода в каталог devfabric среды выполнения.

    • Например, при использовании пакета Azure SDK 1.5 или предыдущих версий скопируйте файл в следующий каталог:


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


    • А при использовании Azure SDK 1.6 или более поздней версии скопируйте файл в этот каталог:


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

  3. Как убедиться, что приложения Azure, выполняющиеся в экземпляре веб-роли, могут найти любой указанный машинный код

    Если приложение Azure ссылается на машинный код в оболочке, созданной с помощью C++/CLI, и выполняется в экземпляре веб-роли, используйте один из следующих методов, чтобы позволить приложению Azure найти указанный машинный код:



    noteПримечание
    В следующей процедуре есть ссылка на проект CppCliWebRole, представленный в образце кода из архива PinvokeCppCliInAzure.zip, который можно загрузить по адресу http://azureunmanagedcode.codeplex.com/. Дополнительные сведения о примерах кода см. в статье Образец кода: Выполнение машинного кода в приложениях Azure.

    Метод 1. Измените переменную среды PATH, затем перезапустите эмулятор вычислений Azure и службы IIS.

    1. Остановите и закройте эмулятор вычислений Azure.

    2. Измените переменную среды PATH так, чтобы она указывала на каталог со скомпилированным неуправляемым кодом.

    3. Введите iisreset в командной строке с повышенными привилегиями.

    4. Нажмите клавишу F5 для выполнения образца кода.

    Метод 2. Использование команды запуска

    Для следующей процедуры машинный код расположен в файле ExampleNativeCode.dll.

    1. Остановите и закройте эмулятор вычислений Azure.

    2. Откройте файл indist.cmd, включенный в проект CppCliWebRole.

    3. Измените следующую строку:

      REM copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
      Чтобы:



      copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
    4. Сохраните проект.

    5. Нажмите клавишу F5 для выполнения образца кода.

    noteПримечание
    Команду запуска можно использовать и для фактических развертываний. Если вы предпочитаете не ссылаться на системный каталог служб IIS, можно создать и запустить скрипт, выполняющий следующие задачи:

    1. изменение переменной среды PATH так, чтобы она указывала на каталог со скомпилированным неуправляемым кодом;

    2. перезапуск служб IIS и всех зависящих от них процессов.

Azure — 64-разрядная платформа, как и узлы (рабочие роли и веб-роли) приложений Azure. Если вы не используете чистую 64-разрядную среду разработки и ваше приложение ссылается на неуправляемый код, приложение будет вызывать ошибки. Можно просто проверить, что весь машинный код, на который вы ссылаетесь, является 64-разрядным — проверьте неуправляемый код с помощью тестовых консольных приложений, которые жестко закодированы для работы как 64-разрядные приложения.

По умолчанию на рабочие роли и веб-роли Azure устанавливаются только библиотеки среды выполнения Visual C++ для Visual C++ 2008. Поэтому машинный код, скомпилированный с использованием библиотеки среды выполнения Visual C++ для других версий Visual C++, приведет к ошибкам в экземплярах рабочих и веб-ролей. Если на одном компьютере установлена Visual Studio 2008 и более поздняя версия, вы можете использовать собственную функцию поддержки нескольких платформ Visual Studio для создания библиотек неуправляемого кода для вашего приложения с помощью набора средств платформы Visual Studio 2008 (компилятор, компоновщик, заголовки и библиотеки). Дополнительные сведения об использовании Visual Studio для создания приложения с помощью набора средств платформы Visual Studio 2008 см. в разделе Практическое руководство. Изменение требуемой версии .NET Framework и набора средств платформы(http://go.microsoft.com/fwlink/?LinkId=324964).

Вы можете добавить задачу запуска с повышенными привилегиями в проект рабочей или веб-роли, чтобы скопировать и установить требуемую версию библиотек среды выполнения. Далее описывается, как создать задачу запуска с повышенными привилегиями для копирования 64-разрядной версии распространяемого пакета оболочки Microsoft Visual C++ 2010 в рабочую или веб-роль и запуска пакета для установки библиотек Visual C++ для Visual C++ 2010 на экземплярах рабочих или веб-ролей. Для других версий Visual C++ требуется распространяемый пакет оболочки, связанный с этой версией:

  1. Создайте папку Startup в вашем проекте рабочей или веб-роли.

  2. Скопируйте файл vcredist_x64.exe (http://go.microsoft.com/fwlink/p/?LinkId=225987) в папку Startup.

  3. Создайте файл startup.cmd в папке Startup.

  4. Измените файл startup.cmd и добавьте следующую строку:


    "%~dps0vcredist_x64.exe" /q /norestart


  5. Измените свойства vcredit_x64.exe и startup.cmd в обозревателе решений Visual Studio. Задайте для параметра Действие построения значение Содержимое, а для параметра Копировать в выходной каталогКопировать более новые.

  6. Измените файл ServiceDefinition.csdef для роли, добавив следующую задачу запуска с повышенными привилегиями для выполнения startup.cmd:


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

Сообщение об ошибке, создаваемое, если эмулятор вычислений Azure не смог загрузить сборку, может не предоставлять четкого описания ошибки. Для устранения неполадок с загрузкой файлов в экземпляре рабочей или веб-роли используйте монитор процессов следующим образом.

  1. Загрузите монитор процессов 2.96 (http://go.microsoft.com/fwlink/p/?LinkID=137175).

  2. Запустите монитор процессов для устранения неполадок с загрузкой файлов в приложениях Azure, запущенных в эмуляторе вычислений Azure.

  3. Задайте параметры фильтра, как показано ниже, для узла эмулятора вычислений Azure. При устранении проблем с приложениями Azure, выполняющимися в проекте рабочей роли, измените фильтр для отображения записей с именем процесса WaWorkerHost.exe, а не WaWebHost.exe.







  4. Найдите сообщения NAME_NOT_FOUND. Это позволит определить, какой файл библиотеки отсутствует. После определения недостающего файла можно сузить область поиска, применив фильтр для определения сообщений, связанных только с этим файлом.

Чтобы приложения Azure могли выполнять 64-разрядный машинный код с использованием P/Invoke, сначала настройте связанные рабочие или веб-роли с полным уровнем доверия .NET. Дополнительные сведения о вызове машинного кода из приложений, запущенных на рабочих или веб-ролях Azure, см. в следующих ресурсах:

В этом разделе описывается пример кода из архива PinvokeCppCliInAzure.zip (http://go.microsoft.com/fwlink/p/?LinkId=236170), который можно загрузить по адресу http://azureunmanagedcode.codeplex.com/.

noteПримечание
При использовании эмулятора вычислений Azure в Visual Studio для работы с образцом кода не обязательно выполнять часть команды запуска, которая устанавливает библиотеки времени выполнения Visual C++, поэтому следующую строку в файле startup.cmd можно закомментировать:

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

Пример содержит проект, создающий собственную DLL-библиотеку ExampleNativeCode.dll. Он был скомпилирован как 64-разрядная библиотека в режиме выпуска, как рекомендуется.

noteПримечание
Закройте и перезапустите эмулятор вычислений Azure при каждом запуске примера кода, если какие-то изменения были внесены в код или переменные среды Windows. Это позволит гарантировать, что машинный код, на который ссылается проект, будет удален из памяти, чтобы его можно было повторно скомпилировать, а все изменения переменных среды будут применены эмулятором вычислений Azure при следующем запуске.

Для образца кода ExampleNativeCode.dll создана оболочка с помощью P/Invoke в проекте ManagedUsingPinvoke и с помощью C++/CLI в проекте ManagedUsingCppCLI.

Код в неуправляемой библиотеке DLL — измененная версия шаблона проекта Win32 по умолчанию, которая выполняет экспорт и содержит одну функцию, отвечающую на все известные вопросы во вселенной, если ответ на эти вопросы — число 42:

EXAMPLENATIVECODE_API int fnExampleNativeCode(void)
{
    return 42;
}

Код P/Invoke и код C++/CLI, использующий эту функцию, очень похожи:

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

Оба образца для рабочих ролей (PInvokeWorkerRole и CppCliWorkerRole) в решении вызывают код одинаково:

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

Оба образца рабочих ролей содержат скомпилированный неуправляемый код и настроены для копирования такого кода в выходной каталог.

Если нажать клавишу F5 для выполнения кода в эмуляторе вычислений Azure, вы должны увидеть следующие результаты.

При вызове машинного кода из приложений Azure, запущенных в экземплярах веб-роли, есть небольшие отличия от вызова кода в экземпляре рабочей роли. Проекты PInvokeWebRole и CppCliWebRole содержат следующий код в немного измененной версии шаблона проекта 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>

Если запустить проект PInvokeWebRole, будет получен приблизительно следующий результат:

Однако если запустить проект CppCliWebRole без изменений, возникнет следующая ошибка:

noteПримечание
Она возникает, даже если для копирования неуправляемого кода в выходной каталог применяются правильные параметры проекта.

Чтобы устранить эту ошибку, воспользуйтесь одним из методов, описанных в разделе Ensure that Azure Applications Running in a Web Role Instance can Locate any Referenced Native Code. После этого вы должны увидеть результаты для CppCliWebRole, аналогичные следующим.

Показ:
© 2014 Microsoft