Postupy: Zařazování řetězců modelu COM pomocí zprostředkovatele komunikace C++
Toto téma ukazuje, jak lze předat BSTR (základní formát řetězce upřednostňovaný v programování modelu COM) ze spravované funkce do nespravované funkce a naopak. Pokud chcete spolupracovat s jinými typy řetězců, přečtěte si následující témata:
Postupy: Zařazování řetězců v kódu Unicode pomocí zprostředkovatele komunikace C++
Postupy: Zařazování řetězců v kódu ANSI pomocí zprostředkovatele komunikace C++
Následující příklady kódu používají spravované, nespravované direktivy #pragma k implementaci spravovaných a nespravovaných funkcí ve stejném souboru, ale tyto funkce vzájemně fungují stejným způsobem, pokud jsou definovány v samostatných souborech. Soubory obsahující pouze nespravované funkce nemusí být kompilovány pomocí /clr (Common Language Runtime Compilation).
Příklad: Předání BSTR ze spravované do nespravované funkce
Následující příklad ukazuje, jak lze předat BSTR (formát řetězce používaný v programování modelu COM) ze spravované do nespravované funkce. Volání spravované funkce používá StringToBSTR k získání adresy BSTR reprezentace obsahu .NET System.String. Tento ukazatel je připnutý pomocí pin_ptr (C++/CLI), aby se při provádění nespravované funkce nezměnila jeho fyzická adresa během cyklu uvolňování paměti. Uvolňování paměti je zakázáno přesouvat paměť, dokud pin_ptr (C++/CLI) nevyjde z rozsahu.
// 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);
}
Příklad: Předání BSTR z nespravované spravované funkce
Následující příklad ukazuje, jak lze BSTR předat z nespravované do spravované funkce. Přijímající spravovaná funkce může buď použít řetězec jako BSTR, nebo ho použít PtrToStringBSTR k převodu String na použití s jinými spravovanými funkcemi. Vzhledem k tomu, že paměť představující BSTR je přidělena na nespravované haldě, není nutné připnout, protože v nespravované haldě neexistuje 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é
Použití zprostředkovatele komunikace C++ (implicitní služba PInvoke)