Compartilhar via


Como: empacotamento 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 seqüências de caracteres, consulte os seguintes tópicos:

O código a seguir exemplos de uso de gerenciado, não gerenciado diretivas # pragma para implementar e gerenciados funções no mesmo arquivo, mas essas funções interoperam da mesma maneira se definidas em arquivos separados.Arquivos que contêm somente funções não gerenciadas não precisará 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.A chamada gerenciado função usa 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 (C++/CLI) para garantir que seu endereço físico não é alterado durante um ciclo de coleta de lixo enquanto executa a função não gerenciada.O coletor de lixo é proibido de mover a memória até o pin_ptr (C++/CLI) 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 para uma função não gerenciada.O recebimento de função gerenciada pode usar a cadeia de caracteres como um BSTR ou use PtrToStringBSTR para convertê-lo para um String para uso com outras funções gerenciadas.Porque a memória que representa o BSTR é alocada no heap gerenciado, sem a fixação é necessária, 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();
}

Consulte também

Referência

Usando interoperabilidade C++ (PInvoke implícita)