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