방법: C++ Interop를 사용하여 COM 문자열 마샬링

이 항목에서는 관리되는 함수에서 관리되지 않는 함수로 BSTR(COM 프로그래밍에 선호되는 기본 문자열 형식)을 전달하는 방법을 보여 줍니다. 다른 문자열 형식과 상호 운용하려면 다음 항목을 참조하세요.

다음 코드 예제에서는 관리되는 관리되지 않는 #pragma 지시문을 사용하여 동일한 파일에서 관리되는 함수와 관리되지 않는 함수를 구현하지만, 이러한 함수는 별도의 파일에 정의된 경우 동일한 방식으로 상호 운용됩니다. 관리되지 않는 함수만 포함하는 파일은 /clr(공용 언어 런타임 컴파일)을 사용하여 컴파일할 필요가 없습니다.

예: 관리되는 함수에서 관리되지 않는 함수로 BSTR 전달

다음 예제에서는 관리되는 함수에서 관리되지 않는 함수로 BSTR(COM 프로그래밍에 사용되는 문자열 형식)을 전달하는 방법을 보여 줍니다. 호출 관리 함수는 .NET System.String의 콘텐츠에 대한 BSTR 표현의 주소를 가져오는 데 사용합니다 StringToBSTR . 이 포인터는 관리되지 않는 함수가 실행되는 동안 가비지 수집 주기 동안 실제 주소가 변경되지 않도록 pin_ptr(C++/CLI)를 사용하여 고정됩니다. 가비지 수집기는 pin_ptr(C++/CLI)가 범위를 벗어날 때까지 메모리를 이동할 수 없습니다.

// MarshalBSTR1.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(BSTR bstr) {
   printf_s("%S", bstr);
}

#pragma managed

int main() {
   String^ s = "test string";

   IntPtr ip = Marshal::StringToBSTR(s);
   BSTR bs = static_cast<BSTR>(ip.ToPointer());
   pin_ptr<BSTR> b = &bs;

   NativeTakesAString( bs );
   Marshal::FreeBSTR(ip);
}

예: 관리되지 않는 함수에서 관리되는 함수로 BSTR 전달

다음 예제에서는 관리되지 않는 함수에서 관리되는 함수로 BSTR을 전달하는 방법을 보여 줍니다. 수신 관리되는 함수는 문자열을 BSTR로 사용하거나 다른 관리되는 함수와 함께 사용하기 위해 변환 String 하는 데 사용할 PtrToStringBSTR 수 있습니다. BSTR을 나타내는 메모리가 관리되지 않는 힙에 할당되므로 관리되지 않는 힙에 가비지 수집이 없으므로 고정이 필요하지 않습니다.

// MarshalBSTR2.cpp
// compile with: /clr
#define WINVER 0x0502
#define _AFXDLL
#include <afxwin.h>

#include <iostream>
using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedTakesAString(BSTR bstr) {
   String^ s = Marshal::PtrToStringBSTR(static_cast<IntPtr>(bstr));
   Console::WriteLine("(managed) convered BSTR to String: '{0}'", s);
}

#pragma unmanaged

void UnManagedFunc() {
   BSTR bs = SysAllocString(L"test string");
   printf_s("(unmanaged) passing BSTR to managed func...\n");
   ManagedTakesAString(bs);
}

#pragma managed

int main() {
   UnManagedFunc();
}

참고 항목

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