Como: Seqüências de caracteres ANSI Marshal usando a interoperabilidade de C++
Este tópico demonstra como seqüências de caracteres ANSI podem ser passados usando a interoperabilidade de C++, mas o.NET Framework String representa as cadeias de caracteres no formato Unicode, portanto, a conversão de ANSI é uma etapa extra. Para interoperar com outros tipos de seqüência de caracteres, consulte os seguintes tópicos:
Como: Cadeias de caracteres do Unicode Marshal usando a interoperabilidade de C++
Como: Empacotar COM seqüências de caracteres usando a interoperabilidade de C++
O código a seguir exemplos de uso do managed, unmanaged diretivas # pragma implementar gerenciados e funções não gerenciadas no mesmo arquivo, mas essas funções interoperam da mesma maneira, se definido em arquivos separados. Porque os arquivos que contêm somente as funções não gerenciadas não precisam ser compilado com /CLR (common Language Runtime Compilation), eles podem manter suas características de desempenho.
Exemplo
O exemplo demonstra passando uma seqüência de caracteres ANSI de uma gerenciado para uma função não gerenciada usando o StringToHGlobalAnsi. Este método aloca memória heap não gerenciada e retorna o endereço depois de executar a conversão. Isso significa que não é necessário nenhum fixação (porque a memória no heap GC não está sendo passada para a função não gerenciada) e o IntPtr retornado de StringToHGlobalAnsi deve ser explicitamente lançado ou uma memória vazam resultados.
// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(const char* p) {
printf_s("(native) received '%s'\n", p);
}
#pragma managed
int main() {
String^ s = gcnew String("sample string");
IntPtr ip = Marshal::StringToHGlobalAnsi(s);
const char* str = static_cast<const char*>(ip.ToPointer());
Console::WriteLine("(managed) passing string...");
NativeTakesAString( str );
Marshal::FreeHGlobal( ip );
}
O exemplo a seguir demonstra o empacotamento de dados necessários para acessar uma seqüência de caracteres ANSI em uma função gerenciada que é chamada por uma função não gerenciada. A função gerenciada, ao receber a seqüência de caracteres nativa, pode usá-lo diretamente ou convertê-lo em uma string gerenciada usando o PtrToStringAnsi método, conforme mostrado.
// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include <vcclr.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
void ManagedStringFunc(char* s) {
String^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
Console::WriteLine("(managed): received '{0}'", ms);
}
#pragma unmanaged
void NativeProvidesAString() {
cout << "(native) calling managed func...\n";
ManagedStringFunc("test string");
}
#pragma managed
int main() {
NativeProvidesAString();
}