Como: realizar realizar marshaling COM strings usando interoperabilidade C++

Este tópico demonstra como um BSTR (o formato de seqüência básica favorecido em programação COM) pode ser passado de um gerenciado para uma função não gerenciada e vice-versa.Para interoperar com outros tipos de cadeias de caracteres, consulte os tópicos a seguir:

Os exemplos de código a seguir usam o gerenciado, não gerenciado para implementar as diretivas # pragma gerenciado e funções não gerenciadas no mesmo arquivo, mas essas funções interoperam da mesma forma se definidas em arquivos separados. Arquivos que contêm somente funções não gerenciadas não precisam ser compilado com o CLR (ComComummon Idioma Tempo de execução ComComumpilation).

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 Sumário de um .NET sistema.String. Esse ponteiro é fixado usando pin_ptr 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 mova a memória até que 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-gerenciados para uma função não gerenciada.A função gerenciada receptor pode use a seqüência de caracteres no sistema autônomo 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 não gerenciada, fixação de nenhuma é necessária, porque não existe uma coleção de lixo na heap não gerenciada.

// 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 a interoperabilidade de C++ (PInvoke implícita)