Cómo: Tener acceso a caracteres en un objeto System::String
Puede acceder a caracteres de un objeto String para 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. Este puntero se puede manipular directamente o anclar y pasar a una función que espera una cadena wchar_t
normal.
Ejemplos
PtrToStringChars
devuelve un Char, que es un puntero interior (también conocido como byref
). Por lo tanto, está sujeto a la recolección de elementos no utilizados. No tiene que anclar este puntero a menos que lo pase a una función nativa.
Observe el código siguiente. El anclaje no es necesario porque ppchar
es un puntero interior y, si el recolector de elementos no utilizados mueve la cadena a la que apunta, también actualizará ppchar
. Sin un pin_ptr (C++/CLI), el código funcionará y no tendrá el posible impacto en el rendimiento causado por el anclaje.
Si pasa ppchar
a una función nativa, debe ser un puntero de anclaje; el recolector de elementos no utilizados no podrá actualizar ningún puntero en el marco de pila no administrado.
// 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
En este ejemplo se muestra dónde se necesita anclar.
// 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 nativo de C++. Por ejemplo, puede usarlo para recorrer una estructura de datos vinculada y realizar inserciones y eliminaciones con un solo 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
}
}