Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este tópico demonstra como um BSTR (o formato básico de cadeia de caracteres favorecido na programação 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, consulte os seguintes tópicos:
Os exemplos de código a seguir usam as diretivas de #pragma gerenciadas e não gerenciadas 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 (Common Language Runtime Compilation).
Exemplo: Passar BSTR de 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 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 .NET System.String. 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 é 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 BSTR de função não gerenciada para 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 gerida de recebimento pode usar a string como um BSTR ou usar PtrToStringBSTR para convertê-la em um String para uso com outras funções geridas. Como a memória que representa o BSTR é alocada no heap não gerenciado, nenhuma fixação é necessária, porque 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();
}