Como realizar marshaling de cadeias de caracteres ANSI usando interop C++
Este tópico demonstra como as cadeias de caracteres ANSI podem ser passadas com a Interoperabilidade do C++, mas o String do .NET Framework representa cadeias de caracteres no formato Unicode, portanto, a conversão em ANSI é uma etapa extra. 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 COM 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. Como os arquivos que contêm apenas funções não gerenciadas não precisam ser compilados com /clr (compilação Common Language Runtime), eles podem manter suas características de desempenho.
Exemplo: Passar cadeia de caracteres ANSI
O exemplo demonstra a passagem de uma cadeia de caracteres ANSI de uma função gerenciada para uma função não gerenciada usando StringToHGlobalAnsi. Esse método aloca memória no heap não gerenciado e retorna o endereço depois de executar a conversão. Isso significa que nenhuma fixação é necessária (porque a memória no heap do GC não está sendo passada para a função não gerenciada) e que o IntPtr retornado StringToHGlobalAnsi precisa ser liberado explicitamente ou ocorrerá uma perda de memória.
// 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 );
}
Exemplo: Marshaling de dados necessário para acessar a cadeia de caracteres Unicode
O exemplo a seguir demonstra o marshaling de dados necessário para acessar uma cadeia de caracteres ANSI em uma função gerenciada que é chamada por uma função não gerenciada. A função gerenciada, ao receber a cadeia de caracteres nativa, pode usá-la diretamente ou convertê-la em uma cadeia de caracteres gerenciada usando o método PtrToStringAnsi, 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();
}