كيفية القيام بما يلي: تنظيم سلاسل ANSI بـاستخدام C++ Interop

يوضح هذا الموضوع كيف يمكن تمرير سلاسل ANSI باستخدام ++Interop C ، ولكن في NET Framework. String تمثل السلاسل في تنسيق Unicode، بحيث أن التحويل إلى ANSI هو خطوة إضافية. للحصول على تشغيل تفاعلي مع أنواع السلاسل الأخرى, راجع المواضيع التالية:

أمثلة التعليمات البرمجية التالية تستخدم توجيهات # pragma ـmanaged, unmanaged لتنفذ الدالات المدارة و غير المدارة في نفس الملف , ولكن تتفاعل هذه الدالات بنفس الطريقة في حالة تعريفها في ملفات منفصلة. لأن الملفات التي تحتوي على دالات غير مدارة فقط لا تحتاج إلى أن يتم تحويلها برمجياً باستخدام /clr (التجميع وقت تشغيل اللغة العامة) ،فإنه يمكنهـا الاحتفاظ بالصفات المميزة لأدائهـا.

مثال

يوضح المثال تمرير سلسلة ANSI من دالة مدارة إلى غير مدارة باستخدام StringToHGlobalAnsi. هذا الطريقة تقوم بتخصيص الذاكرة في كومة الذاكرة المؤقتة الغير المدارة وإرجاع العنوان بعد إجراء التحويل. يعني ذلك أنه ليس من الضروري التثبيت (لأن الذاكرة على وحدة التخزين المؤقت GC لا يتم تمريرهـا للدالة الغير المدارة) وأن IntPtr الذي يتم إرجاعه من StringToHGlobalAnsi يجب أن يتم إصداره بشكل صريح و إلا فسيحدث تسرب فى الذاكرة.

// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>

using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const char* p) {
   printf_s("(native) received '%s'\n", p);
}

#pragma managed

int main() {
   String^ s = gcnew String("sample string");
   IntPtr ip = Marshal::StringToHGlobalAnsi(s);
   const char* str = static_cast<const char*>(ip.ToPointer());

   Console::WriteLine("(managed) passing string...");
   NativeTakesAString( str );

   Marshal::FreeHGlobal( ip );
}

يوضح المثال التالي تنظيم و إرسال البيانات المطلوبين للوصول إلى سلسلة ANSI في الدالة المدارة المُستدعاة بواسطة دالة غير مدارة. الدالة التي تمت إدارتها، عند تلقي السلسلة الأصلية، يمكنها استخدامها مباشرة أو تحويلها إلى سلسلة مدارة باستخدام الأسلوب PtrToStringAnsi كما هو موضح.

// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include <vcclr.h>

using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedStringFunc(char* s) {
   String^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
   Console::WriteLine("(managed): received '{0}'", ms);
}

#pragma unmanaged

void NativeProvidesAString() {
   cout << "(native) calling managed func...\n";
   ManagedStringFunc("test string");
}

#pragma managed

int main() {
   NativeProvidesAString();
}

راجع أيضًا:

المرجع

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