Comment : accéder aux caractères d'un System::String

Vous pouvez accéder aux caractères d’un String objet pour les appels hautes performances aux fonctions non managées qui prennent wchar_t* des chaînes. La méthode génère un pointeur intérieur vers le premier caractère de l’objet String . Ce pointeur peut être manipulé directement ou épinglé et transmis à une fonction qui attend une chaîne ordinaire wchar_t .

Exemples

PtrToStringChars renvoie un Charpointeur intérieur (également appelé « a byref»). Par conséquent, il est soumis au garbage collection. Vous n’avez pas besoin d’épingler ce pointeur, sauf si vous allez le passer à une fonction native.

Prenons le code suivant. L’épinglage n’est pas nécessaire, car ppchar il s’agit d’un pointeur intérieur et si le garbage collector déplace la chaîne vers laquelle il pointe, il est également mis à jour ppchar. Sans pin_ptr (C++/CLI), le code fonctionne et n’a pas de performances potentielles causées par l’épinglage.

Si vous passez ppchar à une fonction native, il doit s’agir d’un pointeur d’épinglage ; le garbage collector ne pourra pas mettre à jour les pointeurs sur le cadre de pile non managé.

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

Cet exemple montre où l’épinglage est nécessaire.

// 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 pointeur intérieur a toutes les propriétés d’un pointeur C++ natif. Par exemple, vous pouvez l’utiliser pour parcourir une structure de données liée et effectuer des insertions et des suppressions à l’aide d’un seul pointeur :

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

Voir aussi

Utilisation de l’interopérabilité C++ (PInvoke implicite)