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:
Postupy: Zařazování řetězců kódování Unicode pomocí C++ Interop
Postupy: Zařazování řetězců ANSI pomocí interoperability C++
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();
}