Variablenleitfaden

Einführung

Wie auf der Seite Übersicht beschrieben, führt der Hostcode RPC-Aufrufe an die Sandbox-Bibliothek aus. Durch das Sandboxing wird der Speicher zwischen den Prozessen getrennt. Der Hostcode kann also nicht direkt auf den Speicher in der Sandbox-Bibliothek zugreifen.

Damit der Hostcode auf Variablen und Speicherblöcke in einem Remote-Prozess zugreifen kann und die Implementierung des Hauptlogikcodes einfacher wird, bietet SAPI eine umfassende Reihe von C++-Klassen. In vielen Fällen können Sie jedoch auch native C-Typen verwenden.

Die Notwendigkeit der speziellen Typen (SAPI-Typen) ergibt sich beim Übergeben von Zeigern an einfache Typen und Speicherblöcke (Strukturen, Arrays).

Wenn Sie beispielsweise eine Funktion aufrufen, die einen Zeiger akzeptiert, muss der Zeiger in einen entsprechenden Zeiger im Speicher der Sandboxed Library konvertiert werden. Das folgende Code-Snippet veranschaulicht dieses Szenario. Statt 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-Headerdateien im SAPI-Projektquellcode. Diese Headerdateien enthalten Klassen und Vorlagen, die verschiedene Datentypen darstellen, z.B.:

  • ::sapi::v::UChar stellt bekannte vorzeichenlose Zeichen dar.
  • ::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 zu finden sind.

SAPI-Pointer

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

Zeigertypen
::PtrNone() Der zugrunde liegende Speicher wird nicht zwischen dem Hostcode-Prozess und dem Prozess der Sandbox-Bibliothek synchronisiert, wenn er an eine Sandbox-API-Funktion übergeben wird.
::PtrBefore() Synchronisiert den Speicher des Objekts, auf das es verweist, bevor der API-Funktionsaufruf in der Sandbox erfolgt. Das bedeutet, dass der lokale Speicher der referenzierten Variable in den Sandboxed Library-Prozess übertragen wird, bevor der Aufruf initiiert wird.
::PtrAfter() Synchronisiert den Speicher des Objekts, auf das es verweist, nach dem Aufruf der Sandboxed API-Funktion. Das bedeutet, dass der Remote-Speicher der referenzierten Variable nach Abschluss des Aufrufs in den Prozessspeicher des Host-Codes übertragen wird.
::PtrBoth() Kombiniert die Funktionen von ::PtrBefore() und ::PtrAfter().

Die Dokumentation zu SAPI-Pointern finden Sie hier.

SAPI-Struktur

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

Das Code-Snippet unten zeigt, wie eine Struktur initialisiert und dann an einen Sandboxed-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 Zeiger auf Adressen in der Sandboxee. Daher müssen Sie Sandboxee-Daten übertragen, bevor sie für den Hostcode zugänglich werden.

SAPI-Arrays

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

In diesem Code-Snippet (aus dem sum-Beispiel) wird die Verwendung des Konstruktors gezeigt, 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()));

SAPI Array bietet alle in SAPI-Pointern beschriebenen Methoden, um ein ::sapi::v::Ptr-Objekt zu erhalten, das für Sandbox-Bibliotheksaufrufe verwendet werden kann.