Procedura: effettuare il marshalling di stringhe COM utilizzando l'interoperabilità C++
In questo argomento viene illustrato come un oggetto BSTR (il formato stringa di base preferito nella programmazione COM) possa essere passato da una funzione gestita a una funzione non gestita e viceversa. Per l'interoperabilità con altri tipi di stringhe, vedere gli argomenti seguenti:
Procedura: Effettuare il marshalling di stringhe Unicode tramite l'interoperabilità C++
Procedura: Effettuare il marshalling di stringhe ANSI tramite l'interoperabilità C++
Gli esempi di codice seguenti usano le direttive #pragma gestite e non gestite per implementare funzioni gestite e non gestite nello stesso file, ma queste funzioni interagiscono nello stesso modo se definite in file separati. I file contenenti solo funzioni non gestite non devono essere compilati con /clr (compilazione Common Language Runtime).
Esempio: Passare BSTR da gestito a funzione non gestita
Nell'esempio seguente viene illustrato come un oggetto BSTR (un formato stringa usato nella programmazione COM) possa essere passato da una funzione gestita a una funzione non gestita. La funzione gestita chiamante usa StringToBSTR per ottenere l'indirizzo di una rappresentazione BSTR del contenuto di un oggetto System.String .NET. Questo puntatore viene aggiunto usando pin_ptr (C++/CLI) per assicurarsi che l'indirizzo fisico non venga modificato durante un ciclo di Garbage Collection mentre viene eseguita la funzione non gestita. Il Garbage Collector non è consentito spostare la memoria finché il pin_ptr (C++/CLI) non esce dall'ambito.
// 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);
}
Esempio: Passare BSTR da una funzione non gestita a una funzione gestita
Nell'esempio seguente viene illustrato come passare un oggetto BSTR da una funzione non gestita a una funzione gestita. La funzione gestita ricevente può usare la stringa in come BSTR o usarla PtrToStringBSTR per convertirla in un String oggetto da usare con altre funzioni gestite. Poiché la memoria che rappresenta la stringa BSTR viene allocata nell'heap non gestito, non è necessaria alcuna aggiunta, perché non è presente garbage collection 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();
}
Vedi anche
Uso delle funzionalità di interoperabilità C++ (PInvoke implicito)