Sdílet prostřednictvím


Postupy: Zařazování řetězců modelu COM pomocí C++ Interop

Toto téma ukazuje, jak BSTR (základní formát řetězců upřednostňovaný při programování v modelu COM) může být předán ze spravované do nespravované funkce a naopak. Více informací o spolupráci s jinými typy řetězců, naleznete v následujících tématech:

Následující příklady kódu používají managed, unmanaged direktivy # pragma k implementaci spravované a nespravované funkce ve stejném souboru, ale tyto funkce spolupracují stejným způsobem, pokud jsou definovány v samostatných souborech. Soubory obsahující pouze nespravované funkce nemusí být kompilovány s /clr (Common Language Runtime Compilation).

Příklad

Následující příklad ukazuje, jak lze předat BSTR (formát řetězců pro programování v modelu COM) ze spravované do nespravované funkce. Volající spravovaná funkce používá StringToBSTR k získání adresy BSTR reprezentující obsah .NET System.String. Tento ukazatel je přišpendlen pomocí pin_ptr čímž je zajištěno, že zatímco je nespravovaná funkce vykonává, tak se jeho fyzická adresa při cyklu uvolňování paměti nezmění. Systém pro uvolňování paměti má zakázáno přesouvat tuto paměť, dokud se pin_ptr nedostane mimo rozsah platnosti.

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

Následující příklad ukazuje, jak může být BSTR předán z nespravované do nespravované funkce. Přijímající spravovaná funkce můžete použít buď jako řetězec v BSTR nebo použít PtrToStringBSTR pro převod na String pro použití s jinými spravovanými funkcemi. Protože paměť představující BSTR je přidělena na nespravované haldě, žádné přišpendlení není nezbytné, protože na nespravované haldě není automatické uvolňování paměti.

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

Viz také

Odkaz

Použití interoperability C++ (implicitně PInvoke)