Procedura: Stringhe COM il marshalling utilizzando l'interoperabilità C++
In questo argomento viene illustrato come un argomento di tipo BSTR (il formato stringa di base più utilizzato nella programmazione COM) può essere passato da una funzione gestita a una funzione non gestita e viceversa.Per informazioni sull'interoperabilità con altri tipi string, vedere i seguenti argomenti:
Procedura: effettuare il marshalling di stringhe Unicode utilizzando l'interoperabilità C++
Procedura: Stringhe ANSI il marshalling utilizzando l'interoperabilità C++
Negli esempi di codice riportati di seguito vengono utilizzate le direttive #pragma managed, unmanaged per implementare funzioni gestite e non gestite nello stesso file. Queste funzioni, tuttavia, vengono eseguite nello stesso modo anche se definite in file diversi.I file che contengono soltanto funzioni non gestite non richiedono necessariamente la compilazione con /clr (Compilazione Common Language Runtime).
Esempio
Nell'esempio di codice riportato di seguito viene illustrato come un argomento di tipo BSTR (un formato stringa utilizzato nella programmazione COM) può essere passato da una funzione gestita a una funzione non gestita.La funzione gestita chiamante utilizza il metodo StringToBSTR per ottenere l'indirizzo di una rappresentazione BSTR del contenuto di un oggetto System.String di .NET.Questo puntatore viene bloccato mediante pin_ptr (C++/CLI) per assicurare che il relativo indirizzo fisico non venga modificato durante un ciclo di Garbage Collection mentre è in esecuzione la funzione non gestita.Al Garbage Collector viene impedito lo spostamento della memoria finché l'oggetto pin_ptr (C++/CLI) non esce dall'ambito in cui è stato dichiarato.
// 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);
}
Nell'esempio di codice riportato di seguito viene illustrato come un argomento di tipo BSTR può essere passato da una funzione non gestita a una funzione gestita.La funzione gestita ricevente può utilizzare la stringa fornita come BSTR oppure utilizzare PtrToStringBSTR per convertirlo in String per l'utilizzo con altre funzioni gestite.Poiché la memoria che rappresenta la stringa BSTR viene allocata nell'heap non gestito, il blocco non è necessario in quanto la Garbage Collection non viene eseguita nell'heap non gestito.
// 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();
}
Vedere anche
Riferimenti
Utilizzo delle funzionalità di interoperabilità C++ (PInvoke implicito)