Postupy: Přístup ke znakům v datech třídy System::String
K znakům objektu String můžete přistupovat pro vysoce výkonná volání nespravovaných funkcí, které přebírají wchar_t*
řetězce. Metoda poskytuje vnitřní ukazatel na první znak objektu String . Tento ukazatel lze manipulovat přímo nebo připnout a předat funkci, která očekává běžný wchar_t
řetězec.
Příklady
PtrToStringChars
vrátí hodnotu Char, což je vnitřní ukazatel (označovaný také jako byref
). Proto podléhá uvolňování paměti. Tento ukazatel nemusíte připnout, pokud ho nepředáte do nativní funkce.
Zvažte následující kód. Připnutí není potřeba, protože ppchar
je vnitřní ukazatel, a pokud systém uvolňování paměti přesune řetězec, na který odkazuje, aktualizuje se také ppchar
. Bez pin_ptr (C++/CLI) bude kód fungovat a nebude mít potenciální výkon způsobený připnutím.
Pokud předáte ppchar
nativní funkci, musí to být připnutý ukazatel. Systém uvolňování paměti nebude moct aktualizovat žádné ukazatele na nespravovaném rámečku 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);
}
abcdefg
Tento příklad ukazuje, kde je potřeba připnout.
// 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
Vnitřní ukazatel má všechny vlastnosti nativního ukazatele C++. Můžete ji například použít k procházení propojené datové struktury a vkládání a odstraňování pomocí jediného 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
}
}
Viz také
Použití zprostředkovatele komunikace C++ (implicitní služba PInvoke)
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro