관리되는/관리되지 않는 코드 상호 운용성에 대한 개요

 

소냐 케세로비치, 프로그램 관리자
David Mortenson, 수석 소프트웨어 디자인 엔지니어
Adam Nathan, 테스트의 수석 소프트웨어 디자인 엔지니어

Microsoft Corporation

2003년 10월

적용 대상:
   Microsoft® .NET Framework
   COM Interop

요약: 이 문서에서는 관리 코드와 비관리 코드 간의 상호 운용성에 대한 기본 사실과 관리 코드에서 관리되지 않는 API에 액세스하고 래핑하고 관리되지 않는 호출자에게 관리되는 API를 노출하기 위한 지침 및 일반적인 사례를 제공합니다. 보안 및 안정성 고려 사항, 성능 데이터 및 개발 프로세스에 대한 일반적인 사례도 강조 표시되어 있습니다. (인쇄된 페이지 14개)

필수 구성 요소: 이 문서의 대상 그룹에는 관리 코드를 사용할 위치에 대해 높은 수준의 결정을 내려야 하는 개발자와 관리자가 포함됩니다. 이를 위해 관리 코드와 비관리 코드 간의 상호 작용 작동 방식과 현재 지침이 특정 시나리오에 적용되는 방식을 이해하는 것이 좋습니다.

콘텐츠

상호 운용성 소개
상호 운용성 지침
보안
안정성
성능
부록 1: 상호 운용성 경계를 넘습니다.
부록 2: 리소스
부록 3: 용어집

상호 운용성 소개

CLR(공용 언어 런타임)은 관리 코드와 COM 구성 요소, COM+ 서비스, Win32® API 및 기타 유형의 비관리 코드와의 상호 작용을 촉진합니다. 데이터 형식, 오류 처리 메커니즘, 생성 및 소멸 규칙 및 디자인 지침은 관리되는 개체 모델과 관리되지 않는 개체 모델 간에 다릅니다. 관리 코드와 비관리 코드 간의 상호 운용을 간소화하고 마이그레이션 경로를 용이하게 하기 위해 CLR interop 계층은 클라이언트와 서버 모두에서 이러한 개체 모델 간의 차이점을 숨겨줍니다.

상호 운용성("interop")은 양방향이므로 다음을 수행할 수 있습니다.

  • 관리 코드에서 관리되지 않는 API 호출

    이 작업은 플랫 API(kernel32.dll 및 user32.dll 같은 DLL에서 노출되는 Win32 API와 같은 정적 DLL 내보내기) 및 COM API(Microsoft® Word, Excel, 인터넷 Explorer, ADO(ActiveX® Data Objects) 등에서 노출되는 개체 모델)에 대해 수행할 수 있습니다.

  • 관리되지 않는 코드에 관리되는 API 노출

    이 작업을 수행하는 예로는 Windows Media® Player와 같은 COM 기반 애플리케이션에 대한 추가 기능을 만들거나 MFC 양식에 관리되는 Windows Forms 컨트롤을 포함하는 것이 있습니다.

다음과 같은 세 가지 보완 기술을 통해 관리/관리되지 않는 상호 작용을 수행할 수 있습니다.

  • 플랫폼 호출(P/Invoke라고도 함)을 사용하면 관리되는 소스 코드에서 서명이 다시 선언되는 한 관리되지 않는 언어로 모든 함수를 호출할 수 있습니다. 이는 Visual Basic® 6.0의 Declare 문에서 제공한 기능과 유사합니다.
  • COM interop을 사용하면 일반 관리형 구성 요소를 사용하는 것과 비슷한 방식으로 모든 관리되는 언어로 COM 구성 요소를 호출할 수 있으며 그 반대의 경우도 마찬가지입니다. COM interop은 CLR에서 제공하는 핵심 서비스와 System.Runtime.InteropServices 네임스페이스의 일부 도구 및 API로 구성됩니다.
  • C++ interop(IJW(Just Works)라고도 함)은 항상 사용되었던 것처럼 플랫 API 및 COM API를 직접 사용할 수 있는 C++관련 기능입니다. 이것은 COM interop보다 더 강력하지만 훨씬 더 많은 주의가 필요합니다. 이 기술을 사용하기 전에 C++ 리소스를 검사 있는지 확인합니다.

상호 운용성 지침

관리 코드에서 관리되지 않는 API 호출

관리되지 않는 API에는 여러 가지 유형이 있으며 이를 호출하는 데 사용할 수 있는 몇 가지 유형의 interop 기술이 있습니다. 이러한 기술을 사용하는 방법과 시기에 대한 제안은 이 섹션에서 설명합니다. 이러한 제안은 매우 일반적이며 모든 시나리오를 다루지는 않습니다. 시나리오를 신중하게 평가하고 시나리오에 적합한 개발 사례 및/또는 솔루션을 적용해야 합니다.

관리되지 않는 플랫 API 호출

관리 코드에서 관리되지 않는 플랫 API로 호출하는 메커니즘은 플랫폼 호출(모든 관리되는 언어로 사용 가능) 또는 C++ interop(C++에서 사용 가능)을 통해 두 가지 메커니즘이 있습니다.

이러한 interop 기술 중 하나를 사용하여 플랫 API를 호출하기로 결정하기 전에 .NET Framework 사용할 수 있는 동일한 기능이 있는지 확인해야 합니다. 가능하면 관리되지 않는 API를 호출하는 대신 .NET Framework 기능을 사용하는 것이 좋습니다.

관리되지 않는 몇 가지 메서드를 호출하거나 간단한 플랫 API를 호출하는 경우 C++ interop 대신 플랫폼 호출을 사용하는 것이 좋습니다. 간단한 플랫 API에 대한 플랫폼 호출 선언을 작성하는 것은 간단합니다. CLR은 DLL 로드 및 모든 매개 변수 마샬링을 처리합니다. 복잡한 플랫 API에 대한 몇 가지 플랫폼 호출 선언을 작성하는 작업조차도 C++ interop을 사용하고 C++로 작성된 완전히 새로운 모듈을 도입하는 비용에 비해 무시할 수 있습니다.

관리되지 않는 복잡한 플랫 API를 래핑하거나 관리 코드가 개발 중인 동안 변경되는 관리되지 않는 플랫 API를 래핑하는 경우 플랫폼 호출 대신 C++ interop을 사용하는 것이 좋습니다. C++ 계층은 매우 얇을 수 있으며 나머지 관리 코드는 원하는 다른 관리 언어로 작성할 수 있습니다. 이러한 시나리오에서 플랫폼 호출을 사용하려면 관리 코드에서 API의 복잡한 부분을 다시 선언하고 관리되지 않는 API와 동기화를 유지하기 위해 많은 노력이 필요합니다. C++ interop을 사용하면 관리되지 않는 API에 직접 액세스할 수 있으므로 다시 작성할 필요가 없고 헤더 파일만 포함하면 됩니다.

COM API 호출

관리 코드에서 COM 구성 요소를 호출하는 방법은 COM interop(모든 관리되는 언어로 사용 가능) 또는 C++ interop(C++에서 사용 가능)을 통해 호출하는 두 가지 방법이 있습니다.

OLE Automation 호환 COM 구성 요소를 호출하는 경우 COM interop을 사용하는 것이 제안됩니다. CLR은 COM 구성 요소 활성화 및 매개 변수 마샬링을 처리합니다.

IDL(인터페이스 정의 언어)을 기반으로 COM 구성 요소를 호출하는 경우 C++ interop을 사용하는 것이 제안입니다. C++ 계층은 매우 얇을 수 있으며 관리 코드의 나머지 부분을 모든 관리되는 언어로 작성할 수 있습니다. COM interop은 형식 라이브러리의 정보를 사용하여 올바른 interop 호출을 수행하지만 형식 라이브러리는 일반적으로 IDL 파일에 있는 모든 정보를 포함하지 않습니다. C++ interop를 사용하면 이러한 COM API에 직접 액세스할 수 있도록 하여 이 문제를 해결합니다.

이미 배송된 COM API를 소유한 회사의 경우 이러한 API에 대한 기본 INTEROP 어셈블리(PIA)를 배송하여 관리되는 클라이언트에서 쉽게 사용할 수 있도록 하는 것이 중요합니다.

관리되지 않는 API를 호출하기 위한 의사 결정 트리

그림 1. 관리되지 않는 API 의사 결정 트리 호출

관리되지 않는 코드에 관리되는 API 노출

관리되는 API를 순전히 관리되지 않는 호출자에게 노출하는 두 가지 기본 방법이 있습니다. COM API 또는 플랫 API로. Visual Studio® .NET을 사용하여 코드를 다시 컴파일하려는 C++ 관리되지 않는 클라이언트의 경우 세 번째 옵션인 C++ interop을 통해 관리되는 기능에 직접 액세스하는 옵션이 있습니다. 이 섹션에서는 이러한 옵션을 사용하는 방법과 시기에 대한 제안을 설명합니다.

관리되는 API에 직접 액세스

관리되지 않는 클라이언트가 C++로 작성된 경우 Visual Studio .NET C++ 컴파일러를 사용하여 "혼합 모드 이미지"로 컴파일할 수 있습니다. 이 작업이 완료되면 관리되지 않는 클라이언트가 관리되는 모든 API에 직접 액세스할 수 있습니다. 그러나 일부 코딩 규칙은 관리되지 않는 코드에서 관리되는 개체에 액세스하는 데 적용됩니다. 자세한 내용은 C++ 설명서를 검사.

직접 액세스는 관리되는 API 개발자의 특별한 고려 사항이 필요하지 않으므로 기본 옵션입니다. 관리되는 API 디자인 지침(DG)에 따라 관리되는 API를 디자인할 수 있으며 관리되지 않는 호출자가 API에 계속 액세스할 수 있다고 확신할 수 있습니다.

관리되는 API를 COM API로 노출

모든 공용 관리형 클래스는 COM interop을 통해 관리되지 않는 클라이언트에 노출될 수 있습니다. COM interop 계층이 모든 COM 배관을 처리하기 때문에 이 프로세스는 구현하기가 매우 쉽습니다. 따라서 예를 들어 모든 관리되는 클래스는 IUnknown, IDispatch, ISupportErrorInfo 및 몇 가지 다른 표준 COM 인터페이스를 구현하는 것으로 나타납니다.

관리되는 API를 COM API로 노출하는 것이 쉽다는 사실에도 불구하고 관리형 및 COM 개체 모델은 매우 다릅니다. 따라서 관리되는 API를 COM에 노출하는 것은 항상 명시적인 디자인 결정이어야 합니다. 관리되는 세계에서 사용할 수 있는 일부 기능은 COM 세계에서 동일하지 않으며 COM 클라이언트에서 사용할 수 없습니다. 이 때문에 관리되는 API 디자인 지침(DG)과 COM과의 호환성 사이에는 긴장감이 있는 경우가 많습니다.

COM 클라이언트가 중요한 경우 관리되는 API 디자인 지침에 따라 관리되는 API를 작성한 다음 COM에 노출될 관리되는 API 주위에 씬 COM 친화적인 관리 래퍼를 작성합니다.

관리되는 API를 플랫 API로 노출

관리되지 않는 클라이언트가 COM을 사용할 수 없는 경우가 있습니다. 예를 들어 플랫 API를 사용하도록 이미 작성되었으며 변경하거나 다시 컴파일할 수 없습니다. C++는 관리되는 API를 플랫 API로 노출할 수 있는 유일한 상위 수준 언어입니다. 이렇게 하는 것은 관리되는 API를 COM API로 노출하는 것만큼 간단하지 않습니다. C++ interop에 대한 고급 지식과 관리되는 세계와 관리되지 않는 세계 간의 차이점이 필요한 매우 고급 기술입니다.

절대적으로 필요한 경우에만 관리되는 API를 플랫 API로 노출합니다. 선택의 여지가 없는 경우 C++ 설명서를 검사 모든 제한 사항을 잘 알고 있어야 합니다.

관리되는 API를 노출하기 위한 의사 결정 트리

그림 2. 관리되는 API 의사 결정 트리 노출

보안

공용 언어 런타임은 어셈블리의 원본에 대한 정보를 기반으로 보호된 리소스에 대한 액세스를 규제하는 보안 시스템 CAS( 코드 액세스 보안 )와 함께 제공됩니다. 관리되지 않는 코드를 호출하는 것은 주요 보안 위험을 초래합니다. 적절한 보안 검사가 없으면 관리되지 않는 코드는 CLR 프로세스에서 관리되는 애플리케이션의 상태를 조작할 수 있습니다. 이러한 리소스에는 CAS 권한 검사가 적용되지 않고 관리되지 않는 코드에서 리소스를 직접 호출할 수도 있습니다. 따라서 관리되지 않는 코드로의 전환은 매우 보호된 작업으로 간주되며 보안 검사 포함해야 합니다. 이 보안 검사 관리되지 않는 코드 전환을 포함하는 어셈블리와 이를 호출하는 모든 어셈블리가 실제로 관리되지 않는 코드를 호출할 수 있는 권한을 요구하는 관리되지 않는 코드 권한을 찾습니다.

전체 보안 검사가 필요하지 않고 구성 요소의 성능 또는 scope 과도하게 제한하는 몇 가지 제한된 interop 시나리오가 있습니다. 관리되지 않는 코드에서 노출된 리소스에 보안 관련성(시스템 시간, 창 좌표 등)이 없거나 리소스가 어셈블리에서 내부적으로만 사용되고 임의 호출자에게 공개적으로 노출되지 않는 경우입니다. 이러한 경우 관련 API의 모든 호출자에 대해 관리되지 않는 코드 권한에 대한 전체 보안 검사 표시하지 않을 수 있습니다. 이 작업은 SuppressUnmanagedCodeSecurity 사용자 지정 특성을 해당 interop 메서드 또는 클래스에 적용하여 수행합니다. 이는 부분적으로 신뢰할 수 있는 코드가 이러한 API를 악용할 수 없다고 판단한 경우 신중한 보안 검토를 가정합니다.

안정성

관리 코드는 관리되지 않는 코드보다 더 안정적이고 강력하도록 설계되었습니다. 이러한 품질을 높이는 CLR 기능의 한 가지 예는 메모리 누수 방지를 위해 사용되지 않는 메모리를 해제하는 가비지 수집입니다. 또 다른 예는 버퍼 오버런 실수 및 기타 형식 관련 오류를 방지하는 데 사용되는 관리형 형식 안전성입니다.

모든 유형의 interop 기술을 사용하는 경우 코드가 순수 관리 코드만큼 안정적이거나 강력하지 않을 수 있습니다. 예를 들어 관리되지 않는 메모리를 수동으로 할당하고 메모리를 완료하면 해제해야 할 수 있습니다.

사소한 interop 코드를 작성하려면 관리되지 않는 코드 작성과 안정성 및 견고성에 대해 동일한 주의가 필요합니다. 모든 interop 코드가 올바르게 작성되더라도 시스템은 관리되지 않는 부분만큼만 안정적입니다.

성능

관리 코드에서 관리되지 않는 코드로 전환할 때마다 약간의 성능 오버헤드가 있습니다. 오버헤드의 양은 사용되는 매개 변수 유형에 따라 달라집니다. CLR interop 계층은 전환 유형 및 매개 변수 형식에 따라 세 가지 수준의 interop 호출 최적화를 사용합니다. JIT(Just-In-Time) 인라인, 컴파일된 어셈블리 스텁 및 해석된 마샬링 스텁(가장 빠른 호출 형식에서 가장 느린 호출 유형 순서).

플랫폼 호출 호출에 대한 대략적인 오버헤드: 10개의 컴퓨터 명령 (x86 프로세서)

COM interop 호출에 대한 대략적인 오버헤드: 50개의 컴퓨터 명령 (x86 프로세서)

이러한 지침에 의해 수행된 작업은 부록 섹션에 표시됩니다. 플랫 API 호출: 단계별 호출 및 COM API 호출: 단계별. COM interop은 호출 중에 가비지 수집기가 관리되지 않는 스레드를 차단하지 않도록 하고 호출 규칙 및 관리되지 않는 예외를 처리하는 것 외에도 현재 런타임 호출 가능 래퍼(RCW)의 호출을 현재 컨텍스트에 적합한 COM 인터페이스 포인터로 변환하는 추가 작업을 수행합니다.

모든 interop 호출에는 약간의 오버헤드가 발생합니다. 이러한 호출이 발생하는 빈도와 메서드 구현 내에서 발생하는 작업의 중요성에 따라 호출당 오버헤드는 무시할 수 있는 것부터 눈에 띄는 것까지 다양할 수 있습니다.

이러한 고려 사항에 따라 다음 목록에서는 유용할 수 있는 몇 가지 일반적인 성능 제안을 제공합니다.

  • 관리 코드와 관리되지 않는 코드 간의 인터페이스를 제어하는 경우 "수다스러운"이 아닌 "청키"로 설정하여 전체 전환 수를 줄입니다.

    수다스러운 인터페이스는 interop 경계의 다른 쪽에서 중요한 작업을 수행하지 않고도 많은 전환을 수행하는 인터페이스입니다. 예를 들어 속성 setter 및 getter는 수다스럽습니다. 청키 인터페이스는 몇 가지 전환만 하는 인터페이스이며 경계의 반대편에서 수행되는 작업의 양이 중요합니다. 예를 들어 데이터베이스 연결을 열고 일부 데이터를 검색하는 메서드는 두툼합니다. 청키 인터페이스에는 더 적은 interop 전환이 포함되므로 일부 성능 오버헤드가 제거됩니다.

  • 가능하면 유니코드/ANSI 변환을 방지합니다.

    문자열을 유니코드에서 ANSI로 변환하는 작업은 비용이 많이 드는 작업입니다. 예를 들어 문자열을 전달해야 하지만 해당 콘텐츠가 중요하지 않은 경우 문자열 매개 변수를 IntPtr 로 선언할 수 있으며 interop 마샬러는 변환을 수행하지 않습니다.

  • 고성능 시나리오의 경우 매개 변수 및 필드를 IntPtr 로 선언하면 사용 편의성과 유지 관리가 부족하지만 성능이 향상됩니다.

    경우에 따라 기본 interop 마샬링에 의존하지 않고 마샬링 클래스에서 사용할 수 있는 메서드를 사용하여 수동 마샬링을 수행하는 것이 더 빠릅니다. 예를 들어 큰 문자열 배열을 interop 경계를 통과해야 하지만 몇 개의 요소만 필요한 경우 배열을 IntPtr 로 선언하고 수동으로 해당 몇 가지 요소에만 액세스하는 것이 훨씬 빠릅니다.

  • InAttributeOutAttribute를 현명하게 사용하여 불필요한 마샬링을 줄입니다.

    interop 마샬러는 호출 전에 특정 매개 변수를 마샬링하고 호출 후 마샬링해야 하는지 여부를 결정할 때 기본 규칙을 사용합니다. 이러한 규칙은 간접 참조 수준 및 매개 변수 형식을 기반으로 합니다. 이러한 작업 중 일부는 메서드의 의미 체계에 따라 필요하지 않을 수 있습니다.

  • 나중에 Marshal.GetLastWin32Error를 호출하는 경우에만 플랫폼에서 SetLastError=false를 사용하여 서명을 호출합니다.

    플랫폼 호출 서명에서 SetLastError=true 를 설정하려면 마지막 오류 코드를 유지하기 위해 interop 계층의 추가 작업이 필요합니다. 이 정보는 이 정보를 사용하는 경우에만 이 기능을 사용하고 호출한 후에 사용합니다.

  • 관리되지 않는 호출이 악용할 수 없는 방식으로 노출되는 경우에만 SuppressUnmanagedCodeSecurityAttribute 를 사용하여 보안 검사 수를 줄입니다.

    보안 검사는 매우 중요합니다. API가 보호된 리소스 또는 중요한 정보를 노출하지 않거나 잘 보호된 경우 광범위한 보안 검사로 인해 불필요한 오버헤드가 발생할 수 있습니다. 그러나 보안 검사 수행하지 않는 비용은 매우 높습니다.

부록 1: 상호 운용성 경계를 넘습니다.

플랫 API 호출: 단계별

그림 3. 플랫 API 호출

  1. LoadLibraryGetProcAddress를 가져옵니다.
  2. 대상 주소가 포함된 서명에서 DllImport 스텁을 빌드합니다.
  3. 호출 수신자 저장 레지스터를 푸시합니다.
  4. DllImport 프레임을 설정하고 프레임 스택에 푸시합니다.
  5. 임시 메모리가 할당된 경우 호출이 완료되면 신속하게 해제할 수 있는 클린 목록을 초기화합니다.
  6. 매개 변수 마샬링 (메모리를 할당할 수 있습니다.)
  7. 가비지 수집 모드를 협동 모드에서 선점 모드로 변경하여 가비지 수집이 언제든지 발생할 수 있도록 합니다.
  8. 대상 주소를 로드하고 호출합니다.
  9. SetLastError 비트가 설정된 경우 GetLastError를 호출하고 결과를 스레드 로컬 스토리지에 저장된 스레드 추상화에 저장합니다.
  10. 다시 협동 가비지 수집 모드로 변경합니다.
  11. PreserveSig=false이고 메서드가 오류 HRESULT를 반환한 경우 예외를 throw합니다.
  12. 예외가 throw되지 않은 경우 백 전파 및참조 별 매개 변수입니다.
  13. 확장 스택 포인터를 원래 값으로 복원하여 호출자가 튀어나온 인수를 고려합니다.

COM API 호출: 단계별

그림 4. COM API 호출

  1. 서명에서 관리되는 스텁에서 관리되지 않는 스텁을 빌드합니다.
  2. 호출 수신자 저장 레지스터를 푸시합니다.
  3. 관리되는 관리되지 않는 COM Interop 프레임을 설정하고 프레임 스택에 푸시합니다.
  4. 전환 중에 사용되는 임시 데이터에 대한 공간을 예약합니다.
  5. 임시 메모리가 할당된 경우 호출이 완료되면 신속하게 해제할 수 있는 클린 목록을 초기화합니다.
  6. 부동 소수점 예외 플래그를 지웁니다(x86만 해당).
  7. 매개 변수 마샬링 (메모리를 할당할 수 있습니다.)
  8. 런타임 호출 가능 래퍼 내에서 현재 컨텍스트에 대한 올바른 인터페이스 포인터를 검색합니다. 캐시된 포인터를 사용할 수 없는 경우 COM 구성 요소에서 QueryInterface를 호출하여 가져옵니다.
  9. 가비지 수집 모드를 협동 모드에서 선점 모드로 변경하여 가비지 수집이 언제든지 발생할 수 있도록 합니다.
  10. vtable 포인터에서 슬롯 번호로 인덱싱하고 대상 주소를 가져오고 호출합니다.
  11. QueryInterface가 이전에 호출된 경우 인터페이스 포인터에서 Release를 호출합니다.
  12. 다시 협동 가비지 수집 모드로 변경합니다.
  13. 서명이 PreserveSig로 표시되지 않으면 오류 HRESULT에 대해 검사 예외를 throw합니다(잠재적으로 IErrorInfo 정보로 채워짐).
  14. 예외가 throw되지 않은 경우 백 전파 및참조 별 매개 변수입니다.
  15. 호출자가 튀어나온 인수를 고려하여 확장 스택 포인터를 원래 값으로 복원합니다.

COM에서 관리되는 API 호출: 단계별

그림 5. COM에서 관리되는 API 호출

  1. 서명에서 관리되지 않는 관리형 스텁을 빌드합니다.
  2. 호출 수신자 저장 레지스터를 푸시합니다.
  3. 관리되지 않는 COM Interop 프레임을 설정하고 프레임 스택에 푸시합니다.
  4. 전환 중에 사용되는 임시 데이터에 대한 공간을 예약합니다.
  5. 가비지 수집 모드를 언제든지 가비지 수집이 발생할 수 있도록 협동 모드에서 선점 모드로 변경합니다.
  6. 인터페이스 포인터에서 COM CCW(호출 가능 래퍼)를 검색합니다.
  7. CCW 내에서 관리되는 개체를 검색합니다.
  8. 필요한 경우 appdomains를 전환합니다.
  9. appdomain이 완전 신뢰가 없는 경우 대상 appdomain에 대해 메서드가 가질 수 있는 링크 요구를 수행합니다.
  10. 임시 메모리가 할당된 경우 호출이 완료되면 신속하게 해제할 수 있는 클린 목록을 초기화합니다.
  11. 매개 변수 마샬링. (메모리를 할당할 수 있습니다.)
  12. 호출할 대상 관리 메서드를 찾습니다. (여기에는 대상 구현에 대한 인터페이스 호출 매핑이 포함됩니다.)
  13. 반환 값을 캐시합니다. 부동 소수점 반환 값인 경우 부동 소수점 레지스터에서 가져옵니다.
  14. 협조적 가비지 수집 모드로 다시 변경합니다.
  15. 예외가 throw된 경우 반환할 HRESULT를 추출하고 SetErrorInfo를 호출합니다.
  16. 예외가 throw되지 않은 경우 back-propagate outby-ref 매개 변수입니다.
  17. 호출자 팝 인수를 고려하여 확장 스택 포인터를 원래 값으로 복원합니다.

부록 2: 리소스

반드시 읽어야 합니다!.NET 및 COM: Adam Nathan의 완전한 상호 운용성 가이드

관리되지 않는 코드와 상호 운용, Microsoft .NET Framework 개발자 가이드

Interop 샘플, Microsoft .NET Framework

아담 네이선의 블로그

Chris Brumme의 블로그

부록 3: 용어집

AppDomain(애플리케이션 도메인) 애플리케이션 도메인은 경량 OS 프로세스와 유사한 것으로 간주될 수 있으며 공용 언어 런타임에서 관리됩니다.
CCW(COM 호출 가능 래퍼) COM 코드에서 활성화된 관리되는 개체를 중심으로 CLR interop 계층에서 만든 특수한 종류의 래퍼입니다. CCW는 데이터 마샬링, 수명 관리, ID 관리, 오류 처리, 올바른 아파트 및 스레딩 전환 등을 제공하여 관리되는 개체 모델과 COM 개체 모델 간의 차이를 숨깁니다. CCW는 관리 코드 구현자가 COM 배관에 대해 아무것도 알 필요가 없는 COM 친화적인 방식으로 관리되는 개체 기능을 노출합니다.
Clr 공용 언어 런타임.
COM interop 관리 코드에서 COM API를 사용하거나 관리되는 API를 관리되지 않는 클라이언트에 COM API로 노출하기 위해 CLR interop 계층에서 제공하는 서비스입니다. COM interop은 모든 관리되는 언어로 사용할 수 있습니다.
C++ interop C++ 언어 컴파일러와 CLR에서 제공하는 서비스로, 동일한 실행 파일에서 관리 코드와 비관리 코드를 직접 혼합하는 데 사용됩니다. C++ interop에는 일반적으로 관리되지 않는 API에 헤더 파일을 포함하고 특정 코딩 규칙을 따르는 작업이 포함됩니다.
복잡한 플랫 API 관리되는 언어로 선언하기 어려운 서명이 있는 API입니다. 예를 들어 변수 크기 구조 매개 변수가 있는 메서드는 관리되는 형식 시스템에 동등한 개념이 없으므로 선언하기 어렵습니다.
Interop 관리 코드와 비관리 코드("네이티브"라고도 함) 간의 모든 유형의 상호 운용성을 다루는 일반 용어입니다. Interop은 CLR에서 제공하는 많은 서비스 중 하나입니다.
Interop 어셈블리 형식 라이브러리에 포함된 COM 형식에 해당하는 관리되는 형식을 포함하는 특수한 형식의 관리되는 어셈블리입니다. 일반적으로 형식 라이브러리에서 형식 라이브러리 가져오기 도구(Tlbimp.exe)를 실행하여 생성됩니다.
관리 코드 CLR의 제어 하에 실행되는 코드를 관리 코드라고 합니다. 예를 들어 C# 또는 Visual Basic .NET으로 작성된 모든 코드는 관리 코드입니다.
플랫폼 호출 관리 코드에서 관리되지 않는 플랫 API를 호출하기 위해 CLR interop 계층에서 제공하는 서비스입니다. 플랫폼 호출은 모든 관리되는 언어로 사용할 수 있습니다.
RCW(런타임 호출 가능 와퍼) 관리 코드에서 활성화된 COM 개체를 중심으로 CLR interop 계층에서 만든 특수한 종류의 래퍼입니다. RCW는 데이터 마샬링, 수명 관리, ID 관리, 오류 처리, 올바른 아파트 및 스레딩 전환 등을 제공하여 관리되는 개체 모델과 COM 개체 모델 간의 차이를 숨깁니다.
비관리 코드 CLR 외부에서 실행되는 코드를 "관리되지 않는 코드"라고 합니다. COM 구성 요소, ActiveX 구성 요소 및 Win32 API 함수는 관리되지 않는 코드의 예입니다.