دليل المتغيّرات

مقدمة

كما هو موضّح في صفحة نظرة عامة، ينفّذ الرمز البرمجي للمضيف طلبات إجراءات عن بُعد إلى "المكتبة المحمية". يؤدي وضع الحماية إلى فصل الذاكرة بين العمليات، وبالتالي لا يمكن لرمز المضيف الوصول مباشرةً إلى الذاكرة في المكتبة المحمية.

لضمان إمكانية وصول "رمز المضيف" إلى المتغيرات وكتل الذاكرة في عملية بعيدة ولتسهيل تنفيذ رمز المنطق الرئيسي، توفر SAPI مجموعة شاملة من فئات C++. ومع ذلك، في العديد من الحالات، سيصبح بإمكانك أيضًا استخدام أنواع C الأصلية.

تظهر الحاجة إلى الأنواع الخاصة (أنواع SAPI) عند تمرير المؤشرات إلى الأنواع البسيطة وكتل الذاكرة (البُنى والمصفوفات).

على سبيل المثال، عند استدعاء دالة تأخذ مؤشرًا، يجب تحويل المؤشر إلى مؤشر مطابق داخل ذاكرة "المكتبة المحصورة في بيئة آمنة". يوضّح مقتطف الرمز البرمجي أدناه هذا السيناريو. بدلاً من مصفوفة من ثلاثة أعداد صحيحة، يتم إنشاء كائن ::sapi::v::Array<int> يمكن تمريره بعد ذلك في طلب البيانات من واجهة برمجة التطبيقات في "المكتبة المحمية":

int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));

للحصول على نظرة عامة شاملة على جميع أنواع SAPI المتاحة، راجِع var_*.hملفات العناوين في رمز مصدر مشروع SAPI. توفر ملفات العناوين هذه فئات ونماذج تمثّل أنواعًا مختلفة من البيانات، مثل:

  • يمثّل ::sapi::v::UChar أحرفًا غير موقَّعة معروفة
  • يمثّل ::sapi::v::Array<int> مصفوفة من الأعداد الصحيحة

أنواع SAPI

يعرض هذا القسم ثلاثة أنواع من واجهة برمجة التطبيقات SAPI التي تظهر عادةً في رمز المضيف.

SAPI Pointers

إذا كانت إحدى الدوال التي سيتم وضعها في بيئة معزولة تتطلّب تمرير مؤشر، يجب الحصول على هذا المؤشر من إحدى طرق PtrXXX() أدناه. يتم تنفيذ هذه الطرق من خلال فئات متغيرات SAPI.

أنواع المؤشرات
::PtrNone() لا تتم مزامنة الذاكرة الأساسية بين عملية "الرمز المضيف" وعملية "المكتبة المحمية" عند تمريرها إلى دالة واجهة برمجة تطبيقات محمية.
::PtrBefore() تتم مزامنة ذاكرة العنصر الذي يشير إليه قبل تنفيذ استدعاء دالة واجهة برمجة التطبيقات المحصورة في بيئة آمنة. وهذا يعني أنّه سيتم نقل الذاكرة المحلية للمتغير المشار إليه إلى عملية "المكتبة المحمية" قبل بدء طلب البيانات.
::PtrAfter() تتم مزامنة ذاكرة العنصر الذي يشير إليه بعد تنفيذ استدعاء دالة واجهة برمجة التطبيقات في البيئة المحمية. وهذا يعني أنّه سيتم نقل الذاكرة البعيدة للمتغير المشار إليه إلى ذاكرة عملية "رمز المضيف" بعد اكتمال المكالمة.
::PtrBoth() تجمع بين وظائف ::PtrBefore() و::PtrAfter().

يمكنك الاطّلاع على مستندات مؤشرات SAPI هنا.

SAPI Struct

يتم توثيق النموذج ::sapi::v::Struct في var_struct.h، ويوفّر دالة إنشائية يمكن استخدامها لتضمين البِنى الحالية. تقدّم السمة SAPI Struct جميع الطرق الموضّحة في مؤشرات SAPI للحصول على عنصر ::sapi::v::Ptr يمكن استخدامه في طلبات المكتبة المحصورة في بيئة الاختبار المعزولة.

يعرض مقتطف الرمز البرمجي أدناه بنية يتم بدء تشغيلها ثم تمريرها إلى استدعاء دالة في وضع الحماية في مثال zlib:

sapi::v::Struct<sapi::zlib::z_stream> strm;

if (ret = api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,
                             version.PtrBefore(), sizeof(sapi::zlib::z_stream));

إذا كان العنصر الحالي يحتوي على مؤشرات، ستشير هذه المؤشرات إلى عناوين في Sandboxee. نتيجةً لذلك، عليك نقل بيانات Sandboxee قبل أن يتمكّن "رمز المضيف" من الوصول إليها.

مصفوفات SAPI

يتم توثيق النموذج ::sapi::v::Array في var_array.h. ويوفّر دالتَين إنشائيتَين، إحداهما يمكن استخدامها لتضمين مصفوفات حالية من العناصر، والأخرى لإنشاء مصفوفة بشكل ديناميكي.

يوضّح مقتطف الرمز البرمجي هذا (المأخوذ من مثال sum) استخدام الدالة الإنشائية التي تتضمّن مصفوفة لا يملكها هذا العنصر:

int arr[10];
sapi::v::Array<int> iarr(arr, ABSL_ARRAYSIZE(arr));

يعرض مقتطف الرمز البرمجي هذا مثالاً على الدالة الإنشائية المستخدَمة لإنشاء مصفوفة بشكل ديناميكي:

sapi::v::Array<uint8_t> buffer(PNG_IMAGE_SIZE(*image.mutable_data()));

تقدّم مصفوفة SAPI جميع الطرق الموضّحة في مؤشرات SAPI للحصول على عنصر ::sapi::v::Ptr يمكن استخدامه في طلبات المكتبة المحصورة.