내보내기(0) 인쇄
모두 확장

Azure 응용 프로그램에서 비관리 코드를 실행하기 위한 최선의 방법

업데이트 날짜: 2014년 6월

Azure 응용 프로그램에 대한 .NET 코드 작성은 Windows 응용 프로그램에 대한 .NET 코드 작성과 대부분 유사합니다. 한 플랫폼 및 다른 플랫폼에 대한 .NET 코드를 작성할 때 알고 있어야 하는 미묘한 차이점이 있습니다. 이 문서에서는 Azure 응용 프로그램에서 비관리/네이티브 코드를 실행하기 위한 권장 사항을 제공합니다.

저자: Christian Martinez, Trace Young 및 Mark Simms

다음 섹션에서는 네이티브 코드를 호출하는 Azure 응용 프로그램을 개발할 때 네이티브 코드가 올바르게 실행되게 하기 위한 권장 사항을 제공합니다.

릴리스 모드에서 컴파일되도록 네이티브 코드를 구성하려면 네이티브 코드 프로젝트를 마우스 오른쪽 단추로 클릭하고 속성을 선택하여 속성 페이지를 표시한 다음 속성 페이지의 빌드 탭에서 사용할 수 있는 릴리스 구성 옵션을 선택합니다.

note참고
msvcr100d.dll 또는 msvcp100d.dll과 같은 DLL이 없다는 런타임 오류는 배포한 네이티브 코드가 디버그 모드에서 컴파일되었음을 나타냅니다. msvcr100d.dll 및 msvcp100d.dll 파일은 재배포 가능 DLL이 아닙니다. 재배포할 C++ DLL 파일 확인에 대한 자세한 내용은 재배포할 DLL 확인(http://go.microsoft.com/fwlink/p/?LinkId=236016)을 참조하십시오.

다음 단계를 수행하여 Azure 계산 에뮬레이터에서 실행될 때 Azure 응용 프로그램이 참조된 네이티브 코드를 찾을 수 있게 합니다.

  1. Visual Studio에서 컴파일된 네이티브 코드 파일에 대한 적절한 속성을 설정합니다.

    컴파일된 네이티브 코드 파일을 프로젝트 항목으로 포함하고 파일의 속성 대화 상자에서 출력 디렉터리로 복사 옵션을 항상 복사로 설정하고 빌드 작업 옵션을 없음으로 설정합니다.

    이렇게 하면 컴파일된 네이티브 코드 파일이 \bin 디렉터리에 복사되고 Azure 응용 프로그램이 Azure 계산 에뮬레이터에서 실행될 때 컴파일된 네이티브 코드 파일을 찾을 수 있습니다.



  2. Azure 계산 에뮬레이터에서 RoleEntry 구현 문제를 해결할 때 컴파일된 네이티브 코드 파일을 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참고
    아래의 단계에서는 http://azureunmanagedcode.codeplex.com/에서 다운로드할 수 있는 PinvokeCppCliInAzure.zip의 샘플 코드와 함께 제공된 CppCliWebRole 프로젝트를 참조합니다. 샘플 코드에 대한 자세한 내용은 예제 코드: Azure 응용 프로그램에서 네이티브 코드 실행를 참조하세요.

    방법 1: PATH 환경 변수를 편집한 다음 Azure 계산 에뮬레이터 및 IIS 다시 시작

    1. Azure 계산 에뮬레이터를 중지하고 종료합니다.

    2. 컴파일된 네이티브 코드가 포함된 디렉터리를 가리키도록 PATH 환경 변수를 편집합니다.

    3. 관리자 권한 명령 프롬프트에서 iisreset을 입력합니다.

    4. F5 키를 눌러 샘플 코드를 실행합니다.

    방법 2: 시작 명령 사용

    다음 단계에서 네이티브 코드는 ExampleNativeCode.dll 파일에 있습니다.

    1. Azure 계산 에뮬레이터를 중지하고 종료합니다.

    2. CppCliWebRole 프로젝트와 함께 포함된 indist.cmd 파일을 엽니다.

    3. 아래의 코드를

      REM copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
      다음과 같이 변경합니다.



      copy "%~dps0ExampleNativeCode.dll" "%windir%\system32\inetsrv"
      
    4. 프로젝트를 저장합니다.

    5. F5 키를 눌러 샘플 코드를 실행합니다.

    note참고
    시작 명령 사용은 실제 배포에도 작동합니다. IIS 시스템 디렉터리에 대한 참조를 사용하지 않으려면 대신 다음을 수행하는 스크립트를 만들어 실행할 수 있습니다.

    1. 컴파일된 네이티브 코드가 포함된 디렉터리를 가리키도록 PATH 환경 변수를 변경합니다.

    2. IIS 및 IIS에 종속된 모든 프로세스를 다시 시작합니다.

Azure는 Azure 응용 프로그램(작업자 및 웹 역할) 호스트와 마찬가지로 64비트 플랫폼입니다. 순수 64비트 개발 환경을 사용하지 않는 경우 응용 프로그램이 네이티브 코드를 참조하면 응용 프로그램이 오류를 throw합니다. 참조하고 있는 모든 네이티브 코드가 64비트인지 확인하려면 64비트 응용 프로그램으로 실행되도록 하드 코딩된 콘솔 테스트 응용 프로그램을 사용하여 네이티브 코드를 간단히 테스트할 수 있습니다.

기본적으로 Visual C++ 2008용 Visual C++ 런타임 라이브러리만 Azure 작업자 및 웹 역할에 설치됩니다. 따라서 다른 버전의 Visual C++용 Visual C++ 런타임 라이브러리에 대해 컴파일된 네이티브 코드는 작업자 및 웹 역할 인스턴스에서 로드되지 않습니다. Visual Studio 2008과 이후 버전이 동일한 컴퓨터에 설치된 경우 Visual Studio의 네이티브 멀티 타기팅 기능을 사용하여 Visual Studio 2008 플랫폼 도구 집합(컴파일러, 링커, 헤더 및 라이브러리)으로 응용 프로그램의 네이티브 라이브러리를 빌드할 수 있습니다. Visual Studio를 사용해서 Visual Studio 2008 플랫폼 도구 집합으로 응용 프로그램을 빌드하는 방법에 대한 자세한 내용은 방법: 대상 프레임워크 및 플랫폼 도구 집합 수정(http://go.microsoft.com/fwlink/?LinkId=324964)을 참조하십시오.

작업자 또는 웹 역할 프로젝트에 승격된 시작 작업을 추가하여 필요한 런타임 라이브러리 버전을 복사하고 설치할 수 있습니다. 다음 단계에서는 높은 권한의 시작 작업을 만들어 64비트 버전의 Microsoft Visual C++ 2010 재배포 가능 패키지를 작업자/웹 역할에 복사하고 재배포 가능 패키지를 실행하여 Visual C++ 2010용 Visual C++ 라이브러리를 작업자/웹 역할 인스턴스에 설치하는 방법에 대해 설명합니다. 다른 버전의 Visual C++에는 해당 버전용 배포 패키지가 필요합니다.

  1. 작업자 또는 웹 역할 프로젝트에 대한 Startup 폴더를 만듭니다.

  2. vcredist_x64.exe(http://go.microsoft.com/fwlink/p/?LinkId=225987)를 Startup 폴더에 복사합니다.

  3. Startup 폴더에 startup.cmd 파일을 만듭니다.

  4. startup.cmd를 편집하고 다음 코드를 추가합니다.


    "%~dps0vcredist_x64.exe" /q /norestart


  5. Visual Studio 솔루션 탐색기에서 vcredit_x64.exestartup.cmd의 속성을 수정합니다. 빌드 작업 옵션을 콘텐츠로 설정하고 출력 디렉터리로 복사 옵션을 변경된 내용만 복사로 설정합니다.

  6. startup.cmd를 실행하기 위해 다음과 같은 높은 권한의 시작 작업을 추가하여 역할에 대한 ServiceDefinition.csdef 파일을 편집합니다.


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

Azure 계산 에뮬레이터에서 어셈블리를 로드할 수 없는 경우 생성되는 오류 메시지는 이해하기가 어려울 수 있습니다. 작업자 또는 웹 역할 호스트 인스턴스에서 파일 로드 문제를 해결하려면 다음과 같이 프로세스 모니터를 사용합니다.

  1. 프로세스 모니터 v2.96(http://go.microsoft.com/fwlink/p/?LinkID=137175)에서 프로세스 모니터를 다운로드합니다.

  2. Azure 계산 에뮬레이터에서 실행될 때 파일을 로드하는 Azure 응용 프로그램의 문제를 해결하기 위해 프로세스 모니터를 시작합니다.

  3. 아래의 그림처럼 Azure 계산 에뮬레이터 호스트에 대한 필터 매개 변수를 설정합니다. 작업자 역할 프로젝트에서 실행되는 Azure 응용 프로그램의 문제를 해결하는 경우 프로세스 이름이 WaWebHost.exe 대신 WaWorkerHost.exe인 항목을 표시하도록 필터를 변경합니다.







  4. NAME_NOT_FOUND 메시지를 모두 찾습니다. 이 메시지는 없는 라이브러리 파일을 확인하는 데 도움이 됩니다. 없는 파일을 확인했으면 해당 파일과 관련된 메시지만 분리하도록 필터를 적용하여 검색 범위를 좁힐 수 있습니다.

Azure 응용 프로그램에서 P/Invoke를 사용하여 64비트 네이티브 코드를 실행할 수 있게 하려면 먼저 .NET 완전 신뢰 수준으로 관련된 작업자 또는 웹 역할을 구성합니다. Azure 작업자 또는 웹 역할에서 실행되는 응용 프로그램에서 네이티브 코드를 호출하는 방법은 다음 리소스를 참조하십시오.

이 섹션에서는 http://azureunmanagedcode.codeplex.com/에서 다운로드할 수 있는 PinvokeCppCliInAzure.zip(http://go.microsoft.com/fwlink/p/?LinkId=236170)의 샘플 코드에 대해 설명합니다.

note참고
Visual Studio에서 Azure 계산 에뮬레이터를 사용하여 샘플 코드를 실행하는 경우 Visual C++ 런타임 라이브러리를 설치하는 시작 명령 부분을 실행할 필요가 없으므로 startup.cmd 파일에서 다음 코드를 주석 처리해야 합니다.

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

샘플 코드에는 ExampleNativeCode.dll이라고 하는 네이티브 DLL을 만드는 프로젝트가 포함되어 있습니다. 권장한 대로 릴리스 모드에서 64비트 라이브러리로 컴파일되어 있습니다.

note참고
코드나 Windows 환경 변수가 변경되는 경우 샘플 코드를 실행할 때마다 Azure 계산 에뮬레이터를 종료하고 다시 시작하십시오. 이렇게 하면 참조된 네이티브 코드가 메모리에서 해제되므로 다시 컴파일될 수 있으며 다음에 실행될 때 Azure 계산 에뮬레이터에서 환경 변수 변경 사항이 적용됩니다.

샘플 코드 ExampleNativeCode.dll은 ManagedUsingPinvoke라는 프로젝트에서 P/Invoke를 사용하여 래핑되고 ManagedUsingCppCLI라는 프로젝트에서 C++/CLI를 사용하여 래핑됩니다.

네이티브 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();
    }
};

솔루션의 두 작업자 역할 샘플(PInvokeWorkerRoleCppCliWorkerRole)은 동일한 방식으로 코드를 호출합니다.

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

두 작업자 역할 샘플은 컴파일된 네이티브 코드를 포함하고 항상 컴파일된 네이티브 코드를 출력 디렉터리에 복사하도록 구성됩니다.

F5 키를 눌러 Azure 계산 에뮬레이터에서 코드를 실행할 때 다음과 같은 출력이 표시됩니다.

작업자 역할 인스턴스에서 실행되는 경우와 비교하여 웹 역할 인스턴스에서 실행되는 Azure 응용 프로그램에서 네이티브 코드를 호출할 때 특정 고려 사항이 적용됩니다. PInvokeWebRoleCppCliWebRole 프로젝트는 조금 수정된 버전의 기본 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