方法 : System::String の文字にアクセスする
更新 : 2007 年 11 月
String オブジェクトの文字にアクセスすると、wchar_t* 文字列を受け取るアンマネージ関数を効率よく呼び出すことができます。このメソッドは、String オブジェクトの 1 文字目への内部ポインタを生成します。このポインタを直接操作するか、固定して、通常の wchar_t 文字列を使用する関数に渡すことができます。
使用例
PtrToStringChars は Char を返します。これは、byref とも呼ばれる内部ポインタです。このため、ガベージ コレクションの対象になります。ネイティブ関数に渡さない限り、このポインタを固定する必要はありません。
次のコードがあるとします。ppchar は内部ポインタであるため、固定する必要はありません。ガベージ コレクタが指している文字列を移動した場合は、ppchar も更新されます。pin_ptr を使用しない場合は、固定が原因でパフォーマンスが低下することなくコードを実行できます。
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
}
}