Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este tópico demonstra como um BSTR (o formato de cadeia de caracteres básico preferencial na programação do COM) pode ser passado de uma função gerenciada para uma função não gerenciada e vice-versa. Para interoperar com outros tipos de cadeias de caracteres, confira os seguintes tópicos:
Como realizar marshaling de cadeias de caracteres Unicode usando interop do C++
Como realizar marshaling de cadeias de caracteres ANSI usando interop do C++
Os exemplos de código a seguir usam as diretivas de #pragma managed, unmanaged para implementar funções gerenciadas e não gerenciadas no mesmo arquivo, mas essas funções interoperam da mesma maneira se definidas em arquivos separados. Os arquivos que contêm apenas funções não gerenciadas não precisam ser compilados com /clr (compilação do Common Language Runtime).
Exemplo: passar o BSTR da função gerenciada para não gerenciada
O exemplo a seguir demonstra como um BSTR (um formato de cadeia de caracteres usado na programação do COM) pode ser passado de uma função gerenciada para uma função não gerenciada. A função gerenciada de chamada usa StringToBSTR para obter o endereço de uma representação BSTR do conteúdo de um System.String do .NET. Esse ponteiro é fixado usando pin_ptr (C++/CLI) para garantir que seu endereço físico não seja alterado durante um ciclo de coleta de lixo enquanto a função não gerenciada é executada. O coletor de lixo fica proibido de mover a memória até que o 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);
}
Exemplo: passar o BSTR de função não gerenciada para a função gerenciada
O exemplo a seguir demonstra como um BSTR pode ser passado de uma função não gerenciada para uma função gerenciada. A função gerenciada receptora pode usar a cadeia de caracteres como um BSTR ou usar PtrToStringBSTR para convertê-la em um String para uso com outras funções gerenciadas. Como a memória que representa o BSTR é alocada no heap não gerenciado, nenhuma fixação é necessária, pois não há 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();
}