发布于 2026-01-06 5 阅读
0

对 Dropbox 的回应:另一种跨平台 C++ 开发视角

对 Dropbox 的回应:另一种跨平台 C++ 开发视角

几周前,Dropbox 在一篇博客文章中宣布,他们决定从代码库中移除 C++。这篇文章引发了诸多反响,尤其是在 C++ 相关的 Reddit 子版块。

我建议你先阅读原文,但这里提供一个简要总结:

2013 年,Dropbox 开始使用 C++ 在 iOS 和 Android 之间共享移动代码,目的是避免重复编写代码。6 年后,由于以下开销,他们改变了策略:

  • 自定义框架和库

  • 定制化的开发环境

  • 移动平台之间的差异

  • 寻找并留住经验丰富的 C++ 开发人员

这些都是很有道理的观点。在Tanker,我们也面临着类似的挑战,我们的跨平台端到端加密 SDK 也存在类似的问题。不过,我们采取了一种不同的方法,能够高效地在包括 iOS 和 Android 在内的多个平台之间共享 C++ 代码;这种方法对我们来说非常有效。

我将分享我对 Dropbox 公告的看法,然后介绍我们采取的解决方案。

剩余障碍

不可否认,编写跨平台 C++ 代码并非易事,而且会带来多种开销。

招聘可能非常棘手,尤其是在需要C++、交叉编译和移动开发方面的专业知识时。此外,内部培训成本高昂,而受训人员在培训几个月后离职的风险,你可能不想承担。

编写和维护特定语言的绑定是一项挑战,拥有 N 个目标平台通常意味着需要 N 个绑定,通过 Java 调试 C++ 代码可能是一场噩梦,更不用说交叉构建的复杂性了。

这些问题在 Dropbox 于 2013 年开始其 C++ 移动开发之旅时就已存在,并且至今仍然存在。

不断变化的环境

幸运的是,此后许多其他方面都有所改善。全球活跃的GitHub开源项目数量有所增加。2013年至2018年间,用C++编写的项目数量增长了7.64倍。

我不同意 Dropbox 的说法,即使用 C++ 最容易预测的开销是构建框架和库的需求

我不知道在制定json11标准时有多少个 C++ JSON 库,但目前isocpp列出了大约 15 个。任何近期项目都应该考虑使用这些库,而不是自己编写一个

C++ 生态系统已经发展得非常成熟,我们现在有很多开源库可供选择,以解决常见的开发问题。

自 2013 年以来,C++ 交叉编译支持也得到了改进,当时公司通常需要自己编写工具:

我们需要一个自定义构建系统,该系统能够创建包含 C++ 代码以及 Java 和 Objective-C 包装器的库,并生成 Xcodebuild 和 Gradle 都能理解的目标。

如今,Android NDK 和 Xcode 都自带最新的 C++ 编译器(尤其是前者)。像 CMake 这样的工具可以生成 Xcode 项目,并可以直接从 Gradle 调用。当然,仍然需要编写一些样板代码,但这远比创建一套完整的构建系统要简单得多。

Tanker 的跨平台开发

正如我之前提到的,Tanker构建了一个端到端加密 SDK,我们的其他产品都基于此。该 SDK 有两个版本,一个是 JavaScript 版本,另一个是 C++ 版本。后者用于我们的 iOS/Android SDK,也可在 Linux/Windows/macOS 上运行。从一开始,我们的目标就与 Dropbox 相同:尽可能多地在不同平台之间共享 C++ 代码。

由于我们的工程师团队规模较小,除非万不得已,否则我们无法花费时间自行重新实现各种库(例如 HTTP、加密、格式化等)。因此,我们尽可能多地使用开源项目并为其做出贡献(例如Modern C++ 的 JSONfmtsqlpp11)。依赖外部项目会带来令人头疼的依赖管理问题,而这正是 C++ 开发面临的主要挑战之一。

如今情况已大不相同,这要归功于 C++ 包管理器的出现(其中最著名的有 Conan、Hunter 和 Vcpkg)。我们选择 Conan 的原因有很多,最主要的是它的灵活性。它已成为我们开发环境的核心要素,因为它使跨平台构建变得非常简单(您可以观看我在2018 年 swampUP 大会上关于此主题的演讲),并为构建和打包适用于多个平台的库和 SDK 提供了一种绝佳的方式。使用 Conan 也使我们能够帮助库的作者们将他们的项目打包。

我们架构设计的一个关键点是允许为多个平台(而不仅仅是移动平台)构建 SDK。这意味着需要用多种编程语言编写绑定。因此,我们选择使用一个精简的 C 接口来封装我们的 C++ API。C 语言简单得多,许多其他语言都可以原生绑定。我们尽可能简化这个接口,因为编写绑定仍然很繁琐。Adi Shavit将这种方法称为“香肠式开发法” 。

正因如此,我们才能轻松编写 iOS 绑定,因为 Objective-C 可以直接调用 C 代码。Android 的绑定仍然需要一些工作,但我们使用了JNA来避免自己编写 JNI 代码。如果将来需要 Go、Rust 或 C# 绑定,那将比只有 C++ 时容易得多。

综上所述

使用各种开源库并用 Conan 进行管理,极大地帮助我们将 SDK 移植到 Linux、macOS、Windows、iOS 和 Android 平台。Dropbox 当时的选择或许有其合理性;然而,如今看来,C++ 似乎是跨平台共享代码的一种非常可行的方式。

我们计划撰写更多文章,介绍 Tanker 中使用 Conan 和 CI 脚本进行依赖管理和交叉构建的过程。


PS:本文最初由Théo Delrieu撰写并发表于Tanker 的 Medium 平台。由于您可能没有 Medium 账号,我们在此转载,以便您有机会在通知栏中看到它。

文章来源:https://dev.to/tanker/reacting-to-dropbox-another-take-on-cross-platform-c-development-42o0