Руководство по переменным

Введение

Как поясняется на странице «Обзор» , хост-код выполняет RPC-вызовы к изолированной библиотеке. Использование изолированной библиотеки приводит к разделению памяти между процессами, и, следовательно, хост-код не может напрямую обращаться к памяти изолированной библиотеки.

Чтобы обеспечить доступ хост-кода к переменным и блокам памяти в удалённом процессе и упростить реализацию основного логического кода, SAPI предоставляет полный набор классов C++. Однако во многих случаях вы также сможете использовать нативные типы C.

Необходимость в специальных типах (типах SAPI) возникает при передаче указателей на простые типы и блоки памяти (структуры, массивы).

Например, при вызове функции, принимающей указатель, этот указатель должен быть преобразован в соответствующий указатель в памяти библиотеки Sandboxed. Приведённый ниже фрагмент кода наглядно иллюстрирует этот сценарий. Вместо массива из трёх целых чисел создаётся объект ::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

Если функция, которую необходимо изолировать, требует передачи указателя, этот указатель следует получить с помощью одного из методов PtrXXX() перечисленных ниже. Эти методы реализованы в классах переменных SAPI.

Типы указателей
::PtrNone() Не синхронизирует базовую память между процессом кода хоста и процессом изолированной библиотеки при передаче в изолированную функцию API.
::PtrBefore() Синхронизирует память объекта, на который указывает, до вызова функции API в изолированной среде. Это означает, что локальная память указанной переменной будет передана процессу библиотеки в изолированной среде до инициации вызова.
::PtrAfter() Синхронизирует память объекта, на который он указывает, после вызова изолированной API-функции. Это означает, что удалённая память указанной переменной будет перенесена в память процесса Host Code после завершения вызова.
::PtrBoth() Объединяет функциональность ::PtrBefore() и ::PtrAfter() .

Документацию по указателям SAPI можно найти здесь .

Структура SAPI

Шаблон ::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 . Он предоставляет два конструктора: один для обёртки существующих массивов элементов, а другой — для динамического создания массива.

В этом фрагменте кода (взятом из примера суммы ) показано использование конструктора, который оборачивает массив, не принадлежащий данному объекту:

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 Array предоставляет все методы, описанные в разделе «Указатели SAPI», для получения объекта ::sapi::v::Ptr , который можно использовать для вызовов изолированной библиотеки.