كيفية القيام بما يلي: الوصول إلى أحرف في 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
   }
}

راجع أيضًا:

المرجع

استخدام PInvoke) C++ Interop الضمني )