Gewusst wie: Zugriff auf Zeichen in einem System::String
Sie können auf Zeichen eines String Objekts für hochleistungsfähige Aufrufe von nicht verwalteten Funktionen zugreifen, die Zeichenfolgen verwenden wchar_t*
. Die Methode gibt einen Innenzeiger auf das erste Zeichen des String Objekts zurück. Dieser Zeiger kann direkt bearbeitet oder angeheftet und an eine Funktion übergeben werden, die eine normale wchar_t
Zeichenfolge erwartet.
Beispiele
PtrToStringChars
gibt einen CharInnenzeiger (auch bekannt als a byref
) zurück. Daher unterliegt sie der Garbage Collection. Sie müssen diesen Zeiger nicht anheften, es sei denn, Sie übergeben ihn an eine systemeigene Funktion.
Betrachten Sie folgenden Code. Das Anheften ist nicht erforderlich, da es sich um ppchar
einen inneren Zeiger handelt, und wenn der Garbage Collector die Zeichenfolge verschiebt, auf die sie verweist, wird sie ebenfalls aktualisiert ppchar
. Ohne eine pin_ptr (C++/CLI) funktioniert der Code und hat keinen potenziellen Leistungstreffer, der durch das Anheften verursacht wird.
Wenn Sie an eine systemeigene Funktion übergeben ppchar
, muss es sich um einen Anheftzeiger handelt. Der Garbage Collector kann keine Zeiger im nicht verwalteten Stapelframe aktualisieren.
// 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
In diesem Beispiel wird gezeigt, wo pinning erforderlich ist.
// 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
Ein Innenzeiger verfügt über alle Eigenschaften eines systemeigenen C++-Zeigers. Sie können sie beispielsweise verwenden, um eine verknüpfte Datenstruktur zu durchlaufen und Einfügungen und Löschungen mit nur einem Zeiger zu erledigen:
// 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
}
}