Cómo: Tener acceso a caracteres en un objeto System::String

Actualización: noviembre 2007

Se puede tener acceso a los caracteres de un objeto String para las llamadas de alto rendimiento a funciones no administradas que toman cadenas wchar_t*. El método produce un puntero interior al primer carácter del objeto String. Se puede manipular este puntero directamente o se puede fijar y pasar a una función que espera una cadena wchar_t normal.

Ejemplo

PtrToStringChars devuelve un valor Char, que es un puntero interior (también conocido como byref). Como tal, está sujeto a la recolección de elementos no utilizados. No es necesario que fije este puntero a menos que vaya a pasarlo a una función nativa.

Observe el código siguiente. No hace falta fijarlo porque ppchar es un puntero interior y, si el recolector de elementos no utilizados mueve la cadena a la que señala, también actualizará ppchar. Sin pin_ptr, el código funcionará y no tendrá el rendimiento potencial debido a la fijación.

Si pasa ppchar a una función nativa, entonces deberá ser un puntero fijado; el recolector de elementos no utilizados no podrá actualizar punteros en el marco no administrado de la pila.

// PtrToStringChars.cpp
// compile with: /clr
#include<vcclr.h>
using namespace System;

int main() {
   String ^ mystring = "abcdefg";

   interior_ptr<const Char> ppchar = PtrToStringChars( mystring );

   for ( ; *ppchar != L'\0'; ++ppchar )
      Console::Write(*ppchar);
}

abcdefg

Este ejemplo muestra dónde es preciso fijar.

// PtrToStringChars_2.cpp
// compile with: /clr
#include <string.h>
#include <vcclr.h>
// using namespace System;

size_t getlen(System::String ^ s) {
   // Since this is an outside string, we want to be secure.
   // To be secure, we need a maximum size.
   size_t maxsize = 256;
   // make sure it doesn't move during the unmanaged call
   pin_ptr<const wchar_t> pinchars = PtrToStringChars(s);
   return wcsnlen(pinchars, maxsize);
};

int main() {
   System::Console::WriteLine(getlen("testing"));
}
7

Un puntero interior tiene todas las propiedades de un puntero de C++ nativo. Por ejemplo, puede utilizarlo para recorrer una estructura de datos vinculada y hacer inserciones y eliminaciones sólo mediante un puntero:

// PtrToStringChars_3.cpp
// compile with: /clr /LD
using namespace System;
ref struct ListNode {
   Int32 elem; 
   ListNode ^ Next;
};

void deleteNode( ListNode ^ list, Int32 e ) { 
   interior_ptr<ListNode ^> ptrToNext = &list;
   while (*ptrToNext != nullptr) {
      if ( (*ptrToNext) -> elem == e )
         *ptrToNext = (*ptrToNext) -> Next;   // delete node
      else
         ptrToNext = &(*ptrToNext) -> Next;   // move to next node
   }
}

Vea también

Referencia

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