Partilhar via


Como realizar marshaling de cadeias de caracteres COM usando interop C++

Este tópico mostra como um BSTR (o formato básico de cadeia de caracteres favorecido em COM que programa) pode ser passado de um gerenciado para uma função não gerenciado, e vice-versa. Para interoperar com outros tipos de cadeias de caracteres, consulte os seguintes tópicos:

Os exemplos de código a seguir usam as políticas de #pragma de gerenciado, não gerenciado para implementar gerenciado e funções não gerenciada no mesmo arquivo, mas essas funções interoperam da mesma forma que se definido em arquivos separados. Os arquivos que contêm somente funções não gerenciado não precisam ser compilados com /clr (compilação do Common Language Runtime).

Exemplo

O exemplo a seguir demonstra como um BSTR (um formato de cadeia de caracteres COM usado na programação) pode ser passado de um gerenciado para uma função não gerenciado. A função gerenciada chamada usa StringToBSTR para obter o endereço de uma representação de BSTR do conteúdo de um .NET System.String. Esse ponteiro é fixado usando pin_ptr (C++/CLI) para garantir que o endereço físico não foi alterada durante um ciclo de coleta de lixo quando a função não gerenciado executar. O coletor de lixo é proibido de mover a memória até que pin_ptr (C++/CLI) saia 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 gerenciada em uma função não gerenciado. A função gerenciada pull pode usar a cadeia de caracteres em como um BSTR ou usar PtrToStringBSTR para convertê-los em String para uso com outras funções gerenciadas. Como a memória que representa o BSTR é atribuída no heap não gerenciado, nenhum fixar-se é necessário, pois não há nenhuma coleta de lixo no heap não 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 interop C++ (PInvoke implícito)