كيفية القيام بما يلي: الوصول إلى أحرف في System::String
يمكنك الوصول إلى الأحرف للكائن String من أجل الاستدعاءات ذات الأداء العالي للدالات غير المدارة التي تأخذ سلاسل wchar_t* . يعطي الأسلوب مؤشرا داخليا يشير إلى الحرف الأول من الكائن String . هذا المؤشر يمكن معالجته بشكل مباشر أو تثبيته وإعادة تمريره إلى دالة من تتوقع سلسلة 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 الأصلي. على سبيل المثال، يمكنك استخدامه لتجتاز بناء بيانات مرتبطة (linked data structure) وقم بإجراء عمليات الإدراج والحذف باستخدام مؤشر واحد فقط:
// 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
}
}