Cómo: Calcular referencias de cadenas ANSI mediante la interoperabilidad de C++
Este tema 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 requiere un paso adicional. Para interoperar con otros tipos de cadenas, vea los temas siguientes:
Cómo: Calcular referencias de cadenas Unicode mediante la interoperabilidad de C++
Cómo: Calcular referencias de cadenas COM mediante la interoperabilidad de C++
En los siguientes ejemplos de código, se utilizan las directivas #pragma managed, unmanaged para implementar funciones administradas y no administradas en el mismo archivo, pero sin que éstas dejen de interactuar como si se hubieran definido en archivos separados. Dado que los archivos que contienen sólo funciones no administradas no necesitan ser compilados con /clr (Compilación de Common Language Runtime), pueden retener sus características de rendimiento.
Ejemplo
El ejemplo muestra el paso de una cadena ANSI de una función administrada a una no administrada utilizando StringToHGlobalAnsi. Este método asigna memoria en el montón no administrado y devuelve la dirección después de realizar la conversión. Esto significa que no es necesario anclar (ya que la memoria del montón GC no se pasa a la función no administrada) y que el valor IntPtr devuelto de StringToHGlobalAnsi se debe liberar 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 );
}
El ejemplo siguiente muestra el cálculo de referencias de datos necesario para tener acceso a una cadena ANSI en una función administrada a la que se llama mediante una función no administrada. La función administrada, cuando recibe la cadena nativa, puede usarla directamente o convertirla en una cadena administrada utilizando el método PtrToStringAnsi, 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();
}