C++ Interop 사용(암시적 PInvoke)

다른 .NET 언어와 달리 Visual C++에서 지원하는 상호 운용성을 활용하면 관리 코드와 비관리 코드를 동일한 응용 프로그램에 배치할 수 있고, managed, unmanaged pragma를 사용하여 동일한 파일에 배치할 수도 있습니다. Visual C++ 개발자는 이러한 상호 운용성을 통해 응용 프로그램의 나머지 부분은 그대로 유지한 채 .NET 기능을 기존 Visual C++ 응용 프로그램에 통합할 수 있습니다.

dllexport, dllimport를 사용하여 관리되는 컴파일 대상에서 관리되지 않는 함수를 호출할 수도 있습니다.

암시적 PInvoke는 함수 매개 변수를 마샬링하는 방식을 지정할 필요가 없거나 DllImportAttribute를 명시적으로 호출할 때 지정할 수 있는 다른 세부 정보를 지정할 필요가 없는 경우에 유용합니다.

Visual C++에서는 두 가지 방법으로 관리되는 함수와 관리되지 않는 함수를 상호 운용할 수 있습니다.

명시적 PInvoke는 .NET Framework에서 지원하며 대부분의 .NET 언어에서 사용할 수 있습니다. 그러나 그 이름에서 알 수 있듯이 C++ Interop는 Visual C++에서만 사용할 수 있습니다.

C++ Interop

C++ Interop는 형식이 더 안전하고, 일반적으로 더 손쉽게 구현할 수 있으며, 관리되지 않는 API를 수정해도 더 많은 융통성을 발휘할 수 있고, 명시적 PInvoke로는 얻을 수 없는 성능 향상을 꾀할 수 있다는 점에서 명시적 PInvoke보다 많은 이점이 있습니다. 그러나 관리되지 않는 소스 코드를 사용할 수 없거나 /clr:safe를 사용하여 컴파일하는 경우에는 C++ Interop를 사용할 수 없습니다. 자세한 내용은 순수형 및 안정형 코드(C++/CLI)를 참조하십시오.

C++ COM Interop

Visual C++에서 지원하는 상호 운용성 기능을 사용하면 COM 구성 요소에 대한 상호 운용 작업을 수행할 때 다른 .NET 언어에 비해 특별한 이점을 얻을 수 있습니다. 모든 COM 인터페이스의 각 멤버를 반드시 노출해야 한다거나 데이터 형식이 제한적으로 지원되는 등, .NET Framework Tlbimp.exe(형식 라이브러리 가져오기)에 적용되는 제한 사항에 구애받지 않은 채, C++ Interop를 사용하면 언제든지 COM 구성 요소에 액세스할 수 있고 별도의 interop 어셈블리를 사용할 필요도 없습니다. 자세한 내용은 .NET에서 네이티브 COM 서버 사용을 참조하십시오.

Blittable 형식

단순한 내장 형식(Blittable 형식 및 비 Blittable 형식 참조)을 사용하는 관리되지 않는 API의 경우 특별한 코딩이 필요하지 않습니다. 이러한 데이터 형식의 경우 메모리에 동일한 표현이 있기 때문입니다. 그러나 더 복잡한 데이터 형식의 경우에는 명시적인 데이터 마샬링이 필요합니다. 예제를 보려면 방법: PInvoke를 사용하여 관리 코드로부터 네이티브 DLL 호출을 참조하십시오.

예제

// vcmcppv2_impl_dllimp.cpp
// compile with: /clr:pure user32.lib
using namespace System::Runtime::InteropServices;

// Implicit DLLImport specifying calling convention
extern "C" int __stdcall MessageBeep(int);

// explicit DLLImport needed here to use P/Invoke marshalling because
// System::String ^ is not the type of the first parameter to printf
[DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl,  CharSet = CharSet::Ansi)]
// or just
// [DllImport("msvcrt.dll")]
int printf(System::String ^, ...); 

int main() {
   // (string literals are System::String by default)
   printf("Begin beep\n");
   MessageBeep(100000);
   printf("Done\n");
}
  

단원 내용

interop 시나리오에서 대리자를 사용하는 방법에 대한 자세한 내용은 delegate를 참조하십시오.

참고 항목

개념

관리 코드에서 네이티브 함수 호출