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:

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();
}

Consulte también

Usar la interoperabilidad de C++ (PInvoke implícito)