Sdílet prostřednictvím


Jak: řetězce Marshal COM C++ Interop pomocí

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 (kompilace společné Language Runtime).

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 (C++/CLI) čí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 (C++/CLI) 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ímání spravované funkce můžete buď použít řetězec v jako parametr BSTR nebo PtrToStringBSTR převést do String pro použití s jinými spravované funkce.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é

Referenční dokumentace

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