Postupy: Přístupy ke znakům v System::String
Můžete přistupovat ke znakům objektu String pro výkonné volání nespravovaných funkcí, které přijímají řetězce wchar_t*. Metoda poskytuje vnitřní ukazatel na první znak objektu String. Tímto ukazatelem lze manipulovat přímo nebo připojením a předáním funkci, která očekává běžný řetězec wchar_t.
Příklad
PtrToStringChars vrací Char, který je vnitřní ukazatel (známý také jako byref). Jako takový je předmětem systému uvolňování kolekce. Není nutné tento ukazatel připnout, pokud ho hodláte předat nativní funkce.
Zvažte následující kod: Připnutí není třeba provádět, neboť ppchar je vnitřním ukazatelem, a pokud systém uvolňování paměti ukáže na přesunutí řetězce, bude se také aktualizovat ppchar. Bez pin_ptr, bude kód pracovat a nebude mít potenciální výkon, což je způsobeno připnutím.
Pokud předáte ppchar nativní funkci, pak to musí být připnutý ukazatel; systém uvolňování paměti nebude moct aktualizovat všechny ukazatele v nespravovaném bloku zásobníku.
// 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);
}
Tento příklad ukazuje, kde je potřeba připnutí
// 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"));
}
Vnitřní ukazatel má všechny vlastnosti nativního C++ ukazatele. Například jej můžete použít k procházení spojené datové struktury a prováďet vložení a odstranění, použitím pouze jednoho ukazatele:
// 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
}
}