Porady: kierowanie ciągów COM za pomocą międzyoperacyjności języka C++
W tym temacie pokazano, jak można przekazać element BSTR (podstawowy format ciągu preferowanego w programowaniu COM) z zarządzanej do niezarządzanej funkcji i na odwrót. Aby uzyskać informacje o współdziałaniu z innymi typami ciągów, zobacz następujące tematy:
Instrukcje: przeprowadzanie marshalingu ciągów Unicode za pomocą międzyoperacyjności języka C++
Instrukcje: przeprowadzanie marshalingu ciągów ANSI za pomocą międzyoperacyjności języka C++
Poniższe przykłady kodu używają zarządzanych, niezarządzanych dyrektyw #pragma do implementowania funkcji zarządzanych i niezarządzanych w tym samym pliku, ale te funkcje współdziałają w taki sam sposób, jeśli są zdefiniowane w oddzielnych plikach. Pliki zawierające tylko funkcje niezarządzane nie muszą być kompilowane za pomocą polecenia /clr (kompilacja środowiska uruchomieniowego języka wspólnego).
Przykład: przekazywanie funkcji BSTR z zarządzanej do niezarządzanej funkcji
W poniższym przykładzie pokazano, jak można przekazać ciąg (format ciągu używany w programowaniu COM) z zarządzanego do funkcji niezarządzanej. Wywołanie funkcji zarządzanej używa StringToBSTR metody w celu uzyskania adresu reprezentacji BSTR zawartości elementu System.String platformy .NET. Ten wskaźnik jest przypięty przy użyciu pin_ptr (C++/CLI), aby upewnić się, że jego adres fizyczny nie zostanie zmieniony podczas cyklu odzyskiwania pamięci podczas wykonywania niezarządzanej funkcji. Moduł odśmiecający elementy bezużyteczne nie może przenosić pamięci, dopóki pin_ptr (C++/CLI) nie przekroczy zakresu.
// 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);
}
Przykład: przekazywanie funkcji BSTR z niezarządzanej do funkcji zarządzanej
W poniższym przykładzie pokazano, jak można przekazać ciąg BSTR z niezarządzanego do funkcji zarządzanej. Funkcja zarządzana odbierającego może użyć ciągu w formacie BSTR lub użyć PtrToStringBSTR go do konwersji na element do String użycia z innymi funkcjami zarządzanymi. Ponieważ pamięć reprezentująca BSTR jest przydzielana na stercie niezarządzanej, nie jest konieczne przypinanie, ponieważ nie ma pamięci na niezarządzanej stercie.
// 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();
}
Zobacz też
Korzystanie z międzyoperacyjności języka C++ (niejawna funkcja PInvoke)