معرفی
همانطور که در صفحه نمای کلی توضیح داده شد، کد میزبان تماس های RPC را با کتابخانه Sandboxed برقرار می کند. Sandboxing منجر به جدایی حافظه بین فرآیندها می شود و بنابراین کد میزبان نمی تواند مستقیماً به حافظه در کتابخانه Sandboxed دسترسی داشته باشد.
برای اطمینان از اینکه کد میزبان میتواند به متغیرها و بلوکهای حافظه در یک فرآیند راه دور دسترسی داشته باشد و اجرای کد منطقی اصلی را سادهتر کند، SAPI مجموعهای جامع از کلاسهای C++ را ارائه میکند. با این حال، در بسیاری از موارد شما همچنین می توانید از نوع C بومی استفاده کنید.
نیاز به انواع خاص (انواع SAPI) هنگام انتقال اشاره گرها به انواع ساده و بلوک های حافظه (ساختارها، آرایه ها) ایجاد می شود.
به عنوان مثال، هنگام فراخوانی تابعی که اشاره گر می گیرد، نشانگر باید به یک اشاره گر مربوطه در داخل حافظه Sandboxed Library تبدیل شود. قطعه کد زیر این سناریو را به تصویر می کشد. به جای آرایه ای از سه عدد صحیح، یک شی ::sapi::v::Array<int>
ایجاد می شود که سپس می تواند در فراخوانی API کتابخانه Sandboxed ارسال شود:
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
اگر تابعی که قرار است sandbox شود نیاز به ارسال نشانگر دارد، این نشانگر باید از یکی از روشهای PtrXXX()
زیر بدست آید. این روش ها توسط کلاس های متغیر SAPI پیاده سازی می شوند.
انواع اشاره گر | |
---|---|
::PtrNone() | هنگامی که به یک تابع API جعبه شنی منتقل می شود، حافظه زیرین را بین فرآیند کد میزبان و فرآیند کتابخانه Sandboxed همگام نمی کند. |
::PtrBefore() | حافظه شیئی را که به آن اشاره می کند قبل از فراخوانی تابع API جعبه شنی همگام می کند. این بدان معنی است که حافظه محلی متغیر اشاره شده قبل از شروع تماس به فرآیند Sandboxed Library منتقل می شود. |
::PtrAfter() | پس از فراخوانی تابع API sandboxed، حافظه شیئی را که به آن اشاره می کند، همگام می کند. این بدان معنی است که حافظه راه دور متغیر اشاره شده پس از تکمیل تماس به حافظه پردازش کد میزبان منتقل می شود. |
::PtrBoth() | عملکردهای ::PtrBefore() و ::PtrAfter() را ترکیب می کند. |
اسناد مربوط به نشانگرهای SAPI را میتوانید در اینجا بیابید.
ساختار SAPI
الگوی ::sapi::v::Struct
در var_struct.h مستند شده است. سازنده ای را فراهم می کند که می تواند برای بسته بندی سازه های موجود استفاده شود. SAPI Struct تمام روش های مشخص شده در SAPI Pointers را برای به دست آوردن یک شی ::sapi::v::Ptr
فراهم می کند که می تواند برای فراخوانی های کتابخانه sandbox استفاده شود.
قطعه کد زیر ساختاری را نشان می دهد که شروع شده و سپس به یک فراخوانی تابع sandbox در مثال 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 مستند شده است. این دو سازنده را فراهم می کند، یکی که می تواند برای بسته بندی آرایه های موجود از عناصر استفاده شود، و دیگری برای ایجاد پویا یک آرایه.
این قطعه کد (برگرفته از مثال مجموع ) استفاده از سازنده ای را نشان می دهد که در اطراف آرایه ای که متعلق به این شی نیست، می پیچد:
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
فراهم میکند که میتواند برای فراخوانیهای کتابخانه sandbox استفاده شود.