方法: 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++ ポインターのすべてのプロパティが含まれています。 たとえば、これを使用してリンクされたデータ構造をウォークし、1 つのポインターのみを使用して挿入と削除を行うことができます。
// 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
}
}