如何:访问 System::String 中的字符

你可以访问 String 对象的字符,以便对采用 wchar_t* 字符串的非托管函数进行高性能调用。 该方法生成指向 String 对象第一个字符的内部指针。 此指针可以直接操作,也可以固定并传递给需要普通 wchar_t 字符串的函数。

示例

PtrToStringChars 返回一个 Char,它是内部指针(也称为 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
   }
}

另请参阅

使用 C++ 互操作(隐式 PInvoke)