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
   }
}

Siehe auch

Verwenden von C++-Interop (implizites PInvoke)