Przewodnik po zmiennych

Wstęp

Jak wyjaśniono na stronie Przegląd, kod hosta wysyła wywołania RPC do biblioteki w trybie piaskownicy. Piaskownica powoduje rozdzielenie pamięci między procesami, więc kod hosta nie może bezpośrednio uzyskać dostępu do pamięci w bibliotece piaskownicy.

Aby kod hosta mógł uzyskiwać dostęp do zmiennych i bloków pamięci w procesie zdalnym, a także ułatwić implementację głównego kodu logicznego, interfejs SAPI udostępnia kompleksowy zestaw klas C++. W wielu przypadkach można jednak użyć natywnych typów C.

Zapotrzebowanie na specjalne typy (typy SAPI) pojawia się podczas przekazywania wskaźników do prostych typów i bloków pamięci (struktur, tablic).

Na przykład podczas wywoływania funkcji używającej wskaźnika należy go przekonwertować na odpowiedni wskaźnik w pamięci Biblioteki piaskownicy. Poniższy fragment kodu ilustruje ten scenariusz. Zamiast tablicy złożonej z 3 liczb całkowitych tworzony jest obiekt ::sapi::v::Array<int>, który można przekazać w wywołaniu interfejsu API biblioteki piaskownicy:

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

Pełne omówienie wszystkich dostępnych typów SAPI znajdziesz w plikach nagłówkowych var_*.h w kodzie źródłowym projektu SAPI. Pliki nagłówka zawierają klasy i szablony reprezentujące różne typy danych, np.:

  • ::sapi::v::UChar reprezentuje dobrze znane niepodpisane znaki
  • ::sapi::v::Array<int> reprezentuje tablicę liczb całkowitych

Typy SAPI

W tej sekcji omawiamy 3 typy SAPI często spotykane w kodzie hosta.

Wskaźniki SAPI

Jeśli funkcja piaskownicy wymaga przekazywania wskaźnika, należy go uzyskać za pomocą jednej z poniższych metod PtrXXX(). Te metody są implementowane przez klasy zmiennych SAPI.

Typy wskaźników
::PtrNone() Nie synchronizuje pamięci bazowej między procesem kodu hosta a procesem biblioteki w trybie piaskownicy, gdy jest przekazywana do funkcji interfejsu API w trybie piaskownicy.
::PtrBefore() Synchronizuje pamięć obiektu, na który wskazuje, przed wywołaniem funkcji interfejsu API w trybie piaskownicy. Oznacza to, że lokalna pamięć wskazywanej zmiennej zostanie przekazana do procesu biblioteki w trybie piaskownicy przed zainicjowaniem wywołania.
::PtrAfter() Synchronizuje pamięć obiektu, na który wskazuje, po wywołaniu funkcji interfejsu API w trybie piaskownicy. Oznacza to, że zdalna pamięć zmiennej wskazującej zostanie przekazana do pamięci procesu kodu hosta po zakończeniu wywołania.
::PtrBoth() Łączy funkcje ::PtrBefore() i ::PtrAfter().

Dokumentację wskaźników SAPI znajdziesz tutaj.

Struktura interfejsu SAPI

Szablon ::sapi::v::Struct jest opisany w pliku var_struct.h. Zawiera on konstruktor, którego można używać do pakowania istniejących struktur. Interfejs SAPI Struct udostępnia wszystkie metody opisane we wskaźnikach SAPI, które umożliwiają uzyskanie obiektu ::sapi::v::Ptr, którego można używać w wywołaniach bibliotek w trybie piaskownicy.

Fragment kodu poniżej pokazuje inicjowanie struktury, a następnie przekazywanie do wywołania funkcji piaskownicy w przykładzie 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));
…

Jeśli istniejąca struktura zawiera wskaźniki, będą one wskazywać adresy w środowisku piaskownicy. W związku z tym musisz przenieść dane piaskownicy, zanim staną się one dostępne dla kodu hosta.

Tablice SAPI

Szablon ::sapi::v::Array został opisany w pliku var_array.h. Zawiera on 2 konstrukcje – jeden do pakowania istniejących tablic elementów, a drugi do dynamicznego tworzenia tablicy.

Ten fragment kodu (pobrany z przykładu z sumą) pokazuje użycie konstruktora obejmującego tablicę, która nie należy do tego obiektu:

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

Ten fragment kodu pokazuje przykład konstruktora używanego do dynamicznego tworzenia tablicy:

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

Tablica SAPI udostępnia wszystkie metody opisane we wskaźnikach SAPI, które pozwalają uzyskać obiekt ::sapi::v::Ptr, którego można używać do wywołań biblioteki w trybie piaskownicy.