Cómo: serializar cadenas ANSI mediante la interoperabilidad de C++
En este tema se muestra cómo se pueden pasar cadenas ANSI mediante la interoperabilidad de C++, pero String de .NET Framework representa cadenas en formato Unicode, por lo que la conversión a ANSI es un paso adicional. Para interoperar con otros tipos de cadenas, consulte los siguientes temas:
Cómo: Serializar cadenas Unicode mediante la interoperabilidad de C++
Cómo: Serializar cadenas COM mediante la interoperabilidad de C++
En los ejemplos de código siguientes se usan las directivas de #pragma managed, unmanaged para implementar funciones administradas y no administradas en el mismo archivo, pero estas funciones interoperan de la misma forma si se definen en archivos independientes. Dado que los archivos que solo contienen funciones no administradas no necesitan compilarse con /clr (compilación de Common Language Runtime), pueden conservar sus características de rendimiento.
Ejemplo: pasar una cadena ANSI
En el ejemplo se muestra cómo pasar una cadena ANSI de una función administrada a una no administrada mediante StringToHGlobalAnsi. Este método asigna memoria del montón no administrado y devuelve la dirección después de realizar la conversión, lo que significa que no es preciso realizar ningún anclado (porque la memoria del montón de GC no se pasa a la función no administrada) y que el valor de IntPtr devuelto de StringToHGlobalAnsi debe liberarse explícitamente o se producirá una pérdida de memoria.
// 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 );
}
Ejemplo: serialización de datos necesaria para acceder a la cadena ANSI
En el ejemplo siguiente se muestra la serialización de datos necesaria para acceder a una cadena ANSI en una función administrada a la que llama una función no administrada. La función administrada, al recibir la cadena nativa, puede usarla directamente o convertirla en una cadena administrada mediante el método PtrToStringAnsi, tal como se muestra.
// 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();
}