变量指南
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
简介
如概览页面中所述,宿主代码会向沙盒库发出 RPC 调用。沙盒化会导致进程之间的内存分离,因此宿主代码无法直接访问沙盒化库中的内存。
为了确保宿主代码可以访问远程进程中的变量和内存块,并简化主逻辑代码的实现,SAPI 提供了一套全面的 C++ 类。不过,在许多情况下,您也可以使用原生 C 类型。
当将指针传递给简单类型和内存块(结构、数组)时,就需要使用特殊类型(SAPI 类型)。
例如,在调用接受指针的函数时,必须将指针转换为沙盒库内存中的相应指针。以下代码段直观地展示了此情形。系统会创建一个 ::sapi::v::Array<int>
对象,而不是一个包含三个整数的数组,然后该对象可以传递到沙盒库的 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 结构体提供了 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 中。它提供两个构造函数,一个可用于封装现有元素数组,另一个可用于动态创建数组。
以下代码段(摘自 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
对象。
如未另行说明,那么本页面中的内容已根据知识共享署名 4.0 许可获得了许可,并且代码示例已根据 Apache 2.0 许可获得了许可。有关详情,请参阅 Google 开发者网站政策。Java 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):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"]],["最后更新时间 (UTC):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."]]