为了账号安全,请及时绑定邮箱和手机立即绑定

将巨大的 C++ 库自动包装到 C 以在 Swift / Go 中导入

将巨大的 C++ 库自动包装到 C 以在 Swift / Go 中导入

Go
qq_花开花谢_0 2022-03-02 19:25:39
假设我在 C++ 中有一个巨大的库(具有大量依赖项,在 GCC 下完整构建需要大约 3 小时)。我想在该库的基础上进行构建,但不想在 C++ 中这样做,而是使用更高效的语言。我如何才能真正桥接或包装那个 extern lib 包,以便我可以用另一种语言访问它并在它之上编程?考虑的语言:迅速走我发现,这两种语言确实为 C 库和代码提供了自动桥接或包装(我实际上不知道包装/桥接之间的区别)。所以,如果我有一些 c 代码,我可以将它放在同一个 Swift 或 Go 项目中,并可以在我的项目中通过简单的导入来使用它。然而,这不适用于两种语言的 C++ 代码。所以我用谷歌搜索了如何将 C++ 库转换为 C 代码或生成自动包装器。我发现了以下内容:swig.org - C++ 库的自动包装器Comeau C++ 编译器 - 自动将 C++ 转换为 C 代码LLVM - 应该能够接受任何输入并将其转换为LLVM 能够提供的任何输出。题:如果使用自动包装或自动桥接,在 Swift / Go 等其他语言的如此庞大的库之上构建是否甚至在可用/现实/可管理的领域?列出的 3 个库 / 程序 / 框架中的哪一个最适合 C++ -> C 的过程(因为 Swift 和 Go 都提供 C 自动包装)。有没有比我目前考虑的更好的选择?仅仅“坚持使用 C++”会更好吗,因为使用任何其他工具来进行包装/桥接过程将远远超过使用 Swift / Go 等更高效语言的好处?谢谢:)免责声明:也可以在 C 中手动包装 C++ 库,但对于如此庞大的库来说,这将花费大量的工作。
查看完整描述

2 回答

?
精慕HU

TA贡献1845条经验 获得超8个赞

Q1:现实吗?

不现实,因为任何大型复杂的 C++ 互操作都会变得过于复杂。自动工具很可能会失败,而手动工作太难了。

Q2:什么是最好的?

我不知道,鉴于 A1 这似乎无关紧要。

Q3:替代方案?Q4:C++ 只是最好的选择吗?

如果您想利用来自另一种语言的现有 C++ 代码,而不管涉及哪种语言,复杂场景中的最佳选择是使用混合方法。

由于非标准 C++ 命名约定,大多数语言提供与 C 而不是 C++ 的互操作。换句话说,几乎每种语言都提供对普通 C 函数的访问,但 C++ 通常不受支持。

由于您的库很复杂,因此最好的解决方案是基于“Facade”模式。创建一个新的 C 库并实现利用 C++ 库的应用程序特定逻辑。尝试将此库设计为尽可能薄。目标不是编写所有业务逻辑,而是提供保存 C++ 对象并调用 C++ 函数的 C 函数。然后,GO 级语言代码将调用此库以使用下面的 C++ 库。这种方法不同于 Q1 方法。在 Q1 中,您尝试对每个 C++ 函数或对象的方法进行一次互操作调用。在 Facade 中,您尝试实现应用程序独有的 C++ 使用场景。

使用 Facade,您可以减少互操作工作的范围,因为您针对的是应用场景。同时,您可以减轻 GO 语言级别的 C++ 复杂性。

例如,您需要使用 C++ 库读取温度传感器。

在 C++ 中,你必须这样做:

  1. 打开文件

  2. 读取流,直到找到 SLIP 终止符

  3. 读一个“记录”

  4. 关闭文件

使用外观,您可以创建一个名为“readTemperature(deviceFileName)”的函数,并且该 C 函数一次执行 4 个调用。

这是一个假的例子,只是为了说明这一点。

使用外观你可能想要隐藏原始 C++ 对象,此时它变成了一个小层。这里的目标是保持专注并平衡您的应用程序需求与泛化以支持您的应用程序。

有趣的是,Facade 方法是提高互操作性能的一种方法。由于需要从语言运行时环境编组并对其进行保护,几乎每种语言的互操作都比正常操作更昂贵。许多互操作调用会减慢应用程序的速度(我们在这里谈论的是数百万)。例如,将 10 个互操作调用合并为 1 个可以提高性能,因为减少了 itnerop 操作的数量。


查看完整回答
反对 回复 2022-03-02
?
千巷猫影

TA贡献1829条经验 获得超7个赞

我使用一个相对简单的过程成功地在 Swift 中包装了一个大型(尽管可能不是“巨大”)C++ 库(数百个头文件)。您直接将项目链接到库。您唯一需要包装的是您编写的(将在 Swift 中调用)实际使用库(在 C++ 包装文件中)的任何新函数。冗长的东西可以留在包装文件中,大多数情况下不做任何修改。有一个简单的小教程对我有帮助:https ://www.swiftprogrammer.info/swift_call_cpp.html

(仅供参考,他省略了一个步骤:在 Build Settings => Search Paths => Library Search Paths(调试和发布)中设置库搜索路径)


查看完整回答
反对 回复 2022-03-02
  • 2 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信