Gewusst wie: Zugriff auf Zeichen in einem System::String

Sie können auf die Zeichen eines String-Objekts zugreifen, um leistungsstarke Aufrufe an nicht verwaltete Funktionen auszuführen, die wchar_t*-Zeichenfolgen akzeptieren. Die Methode gibt einen internen Zeiger auf das erste Zeichen des Objekts String zurück. Dieser Zeiger kann direkt bearbeitet oder angeheftet und an eine Funktion übergeben werden, die eine normale wchar_t Zeichenfolge erwartet.

Important

Interne Zeiger in String-Objekten müssen als const behandelt werden. Ein String Objekt wird als unveränderlich betrachtet und das Ändern seines Inhalts kann die Laufzeit destabilisieren. Weitere Informationen finden Sie unter bewährte Methoden für unsicheren Code – 17. Zeichenfolgenmutationen.

Beispiele

PtrToStringChars gibt einen Char zurück, der ein Innenzeiger ist (auch als byref bezeichnet). Daher unterliegt sie der Garbage Collection. Sie müssen diesen Zeiger nur dann fixieren, wenn Sie ihn an eine native Funktion übergeben.

Betrachten Sie folgenden Code. Ein Fixieren ist nicht erforderlich, da ppchar ein interner Zeiger ist, und wenn der Garbage Collector die Zeichenfolge verschiebt, auf die ppchar zeigt, wird auch aktualisiert. Ohne eine pin_ptr (C++/CLI) funktioniert der Code und hat keinen potenziellen Leistungstreffer, der durch das Anheften verursacht wird.

Wenn Sie ppchar an eine native Funktion übergeben, muss es sich um einen fixierenden Zeiger handeln; der Garbage Collector kann keine Zeiger im nicht verwalteten Stapelrahmen 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

Dieses Beispiel zeigt, wo das Anheften 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)