Практическое руководство. Доступ к символам объекта System::String
Вы можете получить доступ к символам объекта для высокопроизводительных вызовов String неуправляемых функций, которые принимают wchar_t*
строки. Метод возвращает внутренний указатель на первый символ String объекта. Этот указатель можно управлять напрямую или закреплять и передавать в функцию, ожидающую обычной wchar_t
строки.
Примеры
PtrToStringChars
возвращает объект Char, который является внутренним указателем (также известным как a byref
). Таким образом, он подлежит сборке мусора. Вам не нужно закреплять этот указатель, если вы не будете передавать его в собственную функцию.
Рассмотрим следующий код. Закрепление не требуется, так как ppchar
это внутренний указатель, и если сборщик мусора перемещает строку, к ней также будет обновлена ppchar
. Без pin_ptr (C++/CLI) код будет работать и не иметь потенциального снижения производительности, вызванного закреплением.
Если вы передаете ppchar
собственную функцию, то она должна быть закреплением указателя; сборщик мусора не сможет обновить указатели на неуправляемый кадр стека.
// 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
В этом примере показано, где требуется закрепление.
// 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
Внутренний указатель имеет все свойства собственного указателя C++. Например, его можно использовать для обхода связанной структуры данных и вставки и удаления с помощью только одного указателя:
// 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
}
}