Como: Empacotar COM seqüências de caracteres usando a interoperabilidade de C++
Este tópico demonstra como um BSTR (o formato de seqüência básica vantajosa em programação COM) pode ser transmitido de um gerenciado para uma função não gerenciada e vice-versa. Para interoperar com outros tipos de cadeias de caracteres, consulte os seguintes tópicos:
Como: Cadeias de caracteres do Unicode Marshal usando a interoperabilidade de C++
Como: Seqüências de caracteres ANSI Marshal usando a interoperabilidade de C++
O código a seguir exemplos de uso do managed, unmanaged diretivas # pragma implementar gerenciados e funções não gerenciadas no mesmo arquivo, mas essas funções interoperam da mesma maneira, se definido em arquivos separados. Arquivos contendo apenas as funções não gerenciadas não precisam ser compilado com /CLR (common Language Runtime Compilation).
Exemplo
O exemplo a seguir demonstra como um BSTR (um formato de seqüência de caracteres usado em programação COM) pode ser passado de gerenciado para uma função não gerenciada. O calling managed usos da função StringToBSTR para obter o endereço de uma representação BSTR do conteúdo de um.NET System. String. Esse ponteiro é fixado usando pin_ptr para garantir que o seu endereço físico não é alterado durante o ciclo de coleta de lixo enquanto executa a função não gerenciada. O coletor de lixo é proibido, mova a memória até o pin_ptr sai do escopo.
// 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);
}
O exemplo a seguir demonstra como um BSTR pode ser passado de um não gerenciado em uma função não gerenciada. O recebimento de função gerenciada pode usar a seqüência de caracteres como um BSTR ou usar PtrToStringBSTR para convertê-lo para um String para uso com outras funções gerenciadas. Porque a memória que representa a BSTR é alocada no heap gerenciado, fixação não é necessário, porque não há nenhuma coleta de lixo no heap gerenciado.
// 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();
}