Variablenleitfaden

Einführung

Wie auf der Seite Übersicht erläutert, führt der Hostcode RPC-Aufrufe an die Sandbox-Bibliothek aus. Sandboxing führt zu einer Arbeitsspeichertrennung zwischen den Prozessen, sodass der Hostcode nicht direkt auf den Arbeitsspeicher in der Sandboxed Library zugreifen kann.

Um sicherzustellen, dass der Hostcode auf Variablen und Speicherblöcke in einem Remote-Prozess zugreifen kann, und um die Implementierung des Hauptlogikcodes einfacher zu gestalten, stellt SAPI einen umfassenden Satz von C++-Klassen zur Verfügung. In vielen Fällen können Sie jedoch auch native C-Typen verwenden.

Die speziellen Typen (SAPI-Typen) werden benötigt, wenn Zeiger an einfache Typen und Speicherblöcke (Strukturen, Arrays) weitergegeben werden.

Wenn Sie beispielsweise eine Funktion aufrufen, die einen Zeiger verwendet, muss der Zeiger in einen entsprechenden Zeiger im Arbeitsspeicher der Sandboxed Library konvertiert werden. Das folgende Code-Snippet veranschaulicht dieses Szenario. Anstelle eines Arrays mit drei Ganzzahlen wird ein ::sapi::v::Array<int>-Objekt erstellt, das dann im API-Aufruf der Sandboxed Library übergeben werden kann:

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

Eine umfassende Übersicht über alle verfügbaren SAPI-Typen finden Sie in den var_*.h-Header-Dateien im Quellcode des SAPI-Projekts. Diese Header-Dateien enthalten Klassen und Vorlagen, die verschiedene Datentypen darstellen. Beispiele:

  • ::sapi::v::UChar steht für bekannte, unsignierte Zeichen
  • ::sapi::v::Array<int> steht für ein Array von Ganzzahlen.

SAPI-Typen

In diesem Abschnitt werden drei SAPI-Typen vorgestellt, die häufig im Hostcode vorkommen.

SAPI-Zeiger

Wenn für eine Funktion, die in einer Sandbox ausgeführt werden soll, ein Zeiger übergeben werden muss, sollte dieser aus einer der folgenden PtrXXX()-Methoden abgerufen werden. Diese Methoden werden von den SAPI-Variablenklassen implementiert.

Zeigertypen
::PtrNone() Der zugrunde liegende Arbeitsspeicher wird nicht zwischen dem Hostcodeprozess und dem Prozess der Sandbox-Bibliothek synchronisiert, wenn er an eine API-Funktion in einer Sandbox übergeben wird.
::PtrBefore() Synchronisiert den Arbeitsspeicher des Objekts, auf das es verweist, bevor der API-Funktionsaufruf in der Sandbox stattfindet. Das bedeutet, dass der lokale Speicher der punktierten Variablen an den Prozess der Sandbox-Bibliothek übertragen wird, bevor der Aufruf initiiert wird.
::PtrAfter() Synchronisiert den Arbeitsspeicher des Objekts, auf das es verweist, nachdem der API-Funktionsaufruf in der Sandbox ausgeführt wurde. Das bedeutet, dass der Remote-Speicher der punktierten Variablen in den Hostcode-Prozessspeicher übertragen wird, nachdem der Aufruf abgeschlossen wurde.
::PtrBoth() Kombiniert die Funktionalität von ::PtrBefore() und ::PtrAfter().

Die Dokumentation für SAPI-Zeiger finden Sie hier.

SAPI-Struktur

Die Vorlage ::sapi::v::Struct ist in var_struct.h dokumentiert. Sie stellt einen Konstruktor bereit, mit dem vorhandene Strukturen umschlossen werden können. SAPI-Struktur stellt alle in SAPI-Zeigern beschriebenen Methoden bereit, um ein ::sapi::v::Ptr-Objekt abzurufen, das für Bibliotheksaufrufe in einer Sandbox verwendet werden kann.

Das folgende Code-Snippet zeigt eine Struktur, die initiiert und dann an einen Sandbox-Funktionsaufruf im zlib-Beispiel übergeben wird:

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

Wenn Ihre vorhandene Struktur Zeiger enthält, verweisen diese auf Adressen im Sandboxee. Infolgedessen müssen Sie Sandboxee-Daten übertragen, bevor sie für den Hostcode zugänglich sind.

SAPI-Arrays

Die Vorlage ::sapi::v::Array ist in var_array.h dokumentiert. Sie bietet zwei Konstruktoren: einen zum Umschließen bestehender Arrays von Elementen und einen zum dynamischen Erstellen eines Arrays.

Dieses Code-Snippet aus dem Summenbeispiel zeigt die Verwendung des Konstruktors, der ein Array umschließt, das nicht zu diesem Objekt gehört:

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

Dieses Code-Snippet zeigt ein Beispiel für den Konstruktor, der zum dynamischen Erstellen eines Arrays verwendet wird:

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

Das SAPI-Array stellt alle in SAPI-Zeigern beschriebenen Methoden zum Abrufen eines ::sapi::v::Ptr-Objekts bereit, das für Bibliotheksaufrufe in einer Sandbox verwendet werden kann.