了解如何混合使用 c、c++ 和 swift,同时提高 app 的安全性。我们将介绍如何在 swift 代码中找到不安全的 c 和 c++ api 调用位置、如何更安全地调用这些 api,以及如何使 app 中的现有 c 和 c++ 代码默认处于更安全的状态。

视频封面
视频地址

此文章由AI生成,可能存在错误,如有问题,请联系djs66256@163.com

安全混合使用 C、C++ 与 Swift:实现跨语言安全互操作

在现代应用开发中,混合使用 Swift 与 C/C++ 代码的情况十分常见。本文将详细介绍如何在保证安全性的前提下实现跨语言调用,帮助开发者避免常见的安全隐患。

引言

随着 Swift 在应用开发中的普及,许多开发者都会面临与现有 C/C++ 代码库互操作的需求。然而,这种混合编程方式可能带来严重的安全隐患,特别是当涉及到指针操作时。苹果安全语言扩展团队经理 Yeoul 在 WWDC 演讲中详细介绍了如何解决这些问题。

定位不安全调用

Swift 6.2 引入的”严格内存安全”编译模式可以帮助开发者识别潜在的 unsafe 调用。例如:

var imageData = [UInt8](repeating: 0, count: imageDataSize)
filterImage(&imageData, imageData.count)

在启用该模式后,编译器会明确警告这种不安全构造,提示开发者需要标记为”unsafe”。

要在项目中启用严格内存安全模式,开发者需要在 Xcode 项目设置中进行手动配置。这种模式能够标记所有不安全代码并解释其原因,是发现混合编程安全问题的第一道防线。

安全调用 C/C++ 代码

指针安全问题

原始指针最大的安全挑战在于缺乏边界保护和生命周期管理。Swift 6.2 引入了新型安全指针 SpanMutableSpan,既保留了指针的高效性,又内置了安全防护。

添加安全注解

开发者可以通过添加特定注解来提升指针安全性:

  1. 边界保护:使用 __counted_by 注解显式关联指针与元素数量
void invertImage(uint8_t *__counted_by(imageSize) imagePtr __noescape, size_t imageSize);
  1. 生命周期管理:使用 __noescape 声明参数不逃逸函数范围
void applyGrayscale(CxxSpanOfByte imageView __noescape);
  1. 返回值安全:使用 __lifetimebound 确保返回值的生命周期正确
CxxSpanOfByte scanImageRow(CxxSpanOfByte imageView __lifetimebound, size_t width, size_t rowIndex);

安全导入自定义 C++ 类型

对于自定义的 C++ 类型,开发者可以通过特定的注解实现安全导入:

  1. 视图类型:使用 SWIFT_NONESCAPABLE 注解确保不超越所指内存的生命周期
struct ImageView {
  std::span<uint8_t> pixelBytes;
  int width;
  int height;
} SWIFT_NONESCAPABLE;
  1. 引用计数类型:使用 SWIFT_SHARED_REFERENCE 指定引用计数函数
struct ImageBuffer {
  std::vector<uint8_t> data;
  std::atomic<unsigned> refCount;
} SWIFT_SHARED_REFERENCE(retain_image_buffer, release_image_buffer);

ImageBuffer* createImage() SWIFT_RETURNS_RETAINED;

提升 C/C++ 代码安全性

虽然无法完全消除 C/C++ 的安全隐患,但开发者可以采取以下措施提升安全性:

  1. 启用 C++标准库强化功能,对 std::span 等标准容器进行边界检查
  2. 启用 C++不安全缓冲区错误检查,强制使用 std::span 代替原始指针
  3. 使用 C边界安全扩展,通过 __counted_by 等注解为指针添加边界信息

这些安全特性可以在 Xcode 的项目设置中统一启用。

总结与最佳实践

为确保混合语言编程的安全性,开发者应当遵循以下最佳实践:

  1. 在 Swift 项目中启用严格内存安全模式
  2. 为所有 C/C++ API 添加适当的安全注解
  3. 开启 C/C++ 的边界安全特性

苹果正在与开源社区合作完善语言间的安全互操作机制,开发者可以参考以下资源了解更多信息:

相关视频

优化 Swift 代码的内存使用和性能

文档资料

-fbounds-safety: Enforcing bounds safety for C
Safely Mixing Swift and C++