變數指南
透過集合功能整理內容
你可以依據偏好儲存及分類內容。
簡介
如「總覽」頁面所述,主機程式碼會對沙箱程式庫發出 RPC 呼叫。沙箱化會導致程序之間的記憶體分離,因此主機程式碼無法直接存取沙箱程式庫中的記憶體。
為確保主機程式碼可以存取遠端程序中的變數和記憶體區塊,並簡化主要邏輯程式碼的實作方式,SAPI 提供了一整套 C++ 類別。不過,在許多情況下,您也可以使用原生 C 型別。
將指標傳遞至簡單型別和記憶體區塊 (結構、陣列) 時,就需要使用特殊型別 (SAPI 型別)。
舉例來說,呼叫採用指標的函式時,指標必須轉換為 Sandboxed Library 記憶體中的對應指標。以下程式碼片段會以視覺化方式呈現這個情境。系統會建立 ::sapi::v::Array<int>
物件,而非三個整數的陣列,然後將該物件傳遞至 Sandboxed Library 的 API 呼叫:
int arr[3] = {1, 2, 3};
sapi::v::Array<int> sarr(arr, ABSL_ARRAYSIZE(arr));
如要全面瞭解所有可用的 SAPI 類型,請查看 SAPI 專案原始碼中的 var_*.h
標頭檔案。這些標頭檔案提供代表各種類型資料的類別和範本,例如:
::sapi::v::UChar
代表未簽署的知名字元
::sapi::v::Array<int>
代表整數陣列
SAPI 類型
本節將介紹主機程式碼中常見的三種 SAPI 類型。
SAPI 指標
如果要進行沙箱化的函式需要傳遞指標,則應從下列其中一個 PtrXXX()
方法取得指標。這些方法是由 SAPI 變數類別實作。
指標類型 |
::PtrNone() |
傳遞至沙箱 API 函式時,不會在主機程式碼程序和沙箱程式庫程序之間同步處理基礎記憶體。 |
::PtrBefore() |
在沙箱化 API 函式呼叫發生「之前」,同步處理所指向物件的記憶體。
也就是說,在啟動呼叫前,所指變數的本機記憶體會轉移至沙箱化程式庫程序。 |
::PtrAfter() |
在沙箱化 API 函式呼叫發生「後」,同步處理所指向物件的記憶體。
也就是說,在呼叫完成後,所指變數的遠端記憶體會轉移至主機程式碼程序記憶體。 |
::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));
…
如果現有 struct 包含指標,這些指標會指向 Sandboxee 中的位址。因此,您必須先轉移 Sandboxee 資料,才能讓主機程式碼存取。
SAPI 陣列
範本 ::sapi::v::Array
記錄在 var_array.h 中。這個範本提供兩個建構函式,一個可用於包裝現有的元素陣列,另一個則用於動態建立陣列。
下列程式碼片段 (取自 sum 範例) 說明如何使用建構函式包裝不屬於這個物件的陣列:
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
物件。
除非另有註明,否則本頁面中的內容是採用創用 CC 姓名標示 4.0 授權,程式碼範例則為阿帕契 2.0 授權。詳情請參閱《Google Developers 網站政策》。Java 是 Oracle 和/或其關聯企業的註冊商標。
上次更新時間:2025-07-26 (世界標準時間)。
[[["容易理解","easyToUnderstand","thumb-up"],["確實解決了我的問題","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["缺少我需要的資訊","missingTheInformationINeed","thumb-down"],["過於複雜/步驟過多","tooComplicatedTooManySteps","thumb-down"],["過時","outOfDate","thumb-down"],["翻譯問題","translationIssue","thumb-down"],["示例/程式碼問題","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["上次更新時間:2025-07-26 (世界標準時間)。"],[[["\u003cp\u003eSandboxed API (SAPI) provides C++ classes (SAPI Types) to enable the Host Code to interact with memory in the Sandboxed Library, particularly for pointers, structures, and arrays.\u003c/p\u003e\n"],["\u003cp\u003eSAPI Pointers (\u003ccode\u003ePtrNone\u003c/code\u003e, \u003ccode\u003ePtrBefore\u003c/code\u003e, \u003ccode\u003ePtrAfter\u003c/code\u003e, \u003ccode\u003ePtrBoth\u003c/code\u003e) control the synchronization of memory between the Host Code and the Sandboxed Library before and after API calls.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003e::sapi::v::Struct\u003c/code\u003e template allows wrapping existing structures for use in sandboxed calls, requiring pointer synchronization for sandboxee data accessibility.\u003c/p\u003e\n"],["\u003cp\u003eThe \u003ccode\u003e::sapi::v::Array\u003c/code\u003e template enables working with arrays in sandboxed environments, offering constructors for wrapping existing arrays and dynamic array creation.\u003c/p\u003e\n"],["\u003cp\u003eRefer to the \u003ccode\u003evar_*.h\u003c/code\u003e header files in the SAPI project source code for a detailed overview of all available SAPI Types and their usage.\u003c/p\u003e\n"]]],[],null,["Introduction\n\nAs explained on the [Overview](/code-sandboxing/sandboxed-api) page, the Host\nCode makes RPC calls to the Sandboxed Library. Sandboxing results in a memory\nseparation between the processes, and thus the Host Code cannot directly access\nmemory in the Sandboxed Library.\n\nIn order to make sure that the Host Code can access variables and memory blocks\nin a remote process and to make the implementation of the main logic code\nsimpler, SAPI provides a comprehensive set of C++ classes. However, in many\ncases you will also be able to use native C-types.\n\nThe need for the special types (SAPI Types) arises when passing pointers to\nsimple types and memory blocks (structures, arrays).\n\nFor example, when calling a function taking a pointer, the pointer must be\nconverted into a corresponding pointer inside the Sandboxed Library's memory.\nThe below code snippet visualises this scenario. Instead of an array of three\nintegers, a `::sapi::v::Array\u003cint\u003e` object is created which can then be passed\nin the Sandboxed Library's API call: \n\n int arr[3] = {1, 2, 3};\n sapi::v::Array\u003cint\u003e sarr(arr, ABSL_ARRAYSIZE(arr));\n\nFor a comprehensive overview of all available SAPI Types, review the `var_*.h`\nheader files in the [SAPI project source\ncode](https://github.com/google/sandboxed-api/tree/master/sandboxed_api). These\nheader files provide classes and templates representing various types of data,\ne.g.:\n\n- `::sapi::v::UChar` represents well-known unsigned chars\n- `::sapi::v::Array\u003cint\u003e` represents an array of integers\n\nSAPI Types\n\nThis section introduces three SAPI Types that are commonly seen in Host Code.\n\nSAPI Pointers\n\nIf a function to be sandboxed requires passing a pointer, this pointer should be\nobtained from one of the `PtrXXX()` methods below. These methods are implemented\nby the SAPI variable classes.\n\n| Pointer Types ||\n|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `::PtrNone()` | Doesn't synchronize the underlying memory between the Host Code process and the Sandboxed Library process when passed to a sandboxed API function. |\n| `::PtrBefore()` | Synchronizes the memory of the object it points to **before** the sandboxed API function call takes place. This means the local memory of the pointed variable will be transferred to the Sandboxed Library process before the call is initiated. |\n| `::PtrAfter()` | Synchronizes the memory of the object it points to **after** the sandboxed API function call takes place. This means the remote memory of the pointed variable will be transferred to the Host Code process memory **after** the call has been completed. |\n| `::PtrBoth()` | Combines the functionality of `::PtrBefore()` and `::PtrAfter()`. |\n\nThe documentation for SAPI pointers can be found\n[here](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/var_pointable.h).\n\nSAPI Struct\n\nThe template `::sapi::v::Struct` is documented in\n[var_struct.h](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/var_struct.h).\nIt provides a constructor that can be used to wrap existing structures. SAPI\nStruct provides all methods outlined in [SAPI Pointers](#sapi_pointers) to\nobtain a `::sapi::v::Ptr` object that can be used for sandboxed library calls.\n\nThe code snippet below shows a structure being initiated and then passed to a\nsandboxed function call in the [zlib\nexample](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/examples/zlib/main_zlib.cc): \n\n sapi::v::Struct\u003csapi::zlib::z_stream\u003e strm;\n ...\n if (ret = api.deflateInit_(strm.PtrBoth(), Z_DEFAULT_COMPRESSION,\n version.PtrBefore(), sizeof(sapi::zlib::z_stream));\n ...\n\nIf your existing struct contains pointers, then those pointers will point to\naddresses in the Sandboxee. In consequence, you will have to transfer Sandboxee\ndata before it becomes accessible to the Host Code.\n\nSAPI Arrays\n\nThe template `::sapi::v::Array` is documented in\n[var_array.h](https://github.com/google/sandboxed-api/blob/main/sandboxed_api/var_array.h).\nIt provides two constructors, one that can be used to wrap existing arrays of\nelements, and another one to dynamically create an array.\n\nThis code snippet (taken from the [sum\nexample](/code-sandboxing/sandboxed-api/examples#sum)) shows the use of the\nconstructor that wraps around an array which is not owned by this object: \n\n int arr[10];\n sapi::v::Array\u003cint\u003e iarr(arr, ABSL_ARRAYSIZE(arr));\n\nThis code snippet shows an example of the constructor used to dynamically create\nan array: \n\n sapi::v::Array\u003cuint8_t\u003e buffer(PNG_IMAGE_SIZE(*image.mutable_data()));\n\nSAPI Array provides all methods outlined in [SAPI Pointers](#sapi_pointers) to\nobtain a `::sapi::v::Ptr` object that can be used for sandboxed library calls."]]