Gör så här: Hantera COM-strängar med C++ Interop

Det här avsnittet visar hur en BSTR (det grundläggande strängformatet som prioriteras i COM-programmering) kan skickas från en hanterad till en ohanterad funktion och vice versa. Information om hur du samverkar med andra strängtyper finns i följande avsnitt:

I följande kodexempel används de hanterade, ohanterade #pragma-direktiven för att implementera hanterade och ohanterade funktioner i samma fil, men dessa funktioner samverkar på samma sätt om de definieras i separata filer. Filer som endast innehåller ohanterade funktioner behöver inte kompileras med /clr (Common Language Runtime Compil).

Exempel: Skicka BSTR från hanterad till ohanterad funktion

I följande exempel visas hur en BSTR (ett strängformat som används i COM-programmering) kan skickas från en hanterad till en ohanterad funktion. Den anropande hanterade funktionen använder StringToBSTR för att hämta adressen för en BSTR-representation av innehållet i en .NET System.String. Den här pekaren fästs med pin_ptr (C++/CLI) för att säkerställa att dess fysiska adress inte ändras under en sophanteringscykel medan den ohanterade funktionen körs. Skräpinsamlaren får inte flytta minnet förrän pin_ptr (C++/CLI) hamnar utanför omfånget.

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

Exempel: Skicka BSTR från ohanterad till hanterad funktion

I följande exempel visas hur en BSTR kan skickas från en ohanterad till en hanterad funktion. Den mottagande hanterade funktionen kan antingen använda strängen som en BSTR eller använda PtrToStringBSTR för att konvertera den till en String för användning tillsammans med andra hanterade funktioner. Eftersom minnet som representerar BSTR allokeras på den ohanterade heapen krävs ingen fästning, eftersom det inte finns någon skräpinsamling på den ohanterade heapen.

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

Se även

Använda C++ Interop (implicit PInvoke)