【问题标题】:Dynamically Bind extern(Objective-C) Classes in D在 D 中动态绑定 extern(Objective-C) 类
【发布时间】:2020-12-22 20:11:14
【问题描述】:

我想在我的 D 应用程序中大量使用 extern (Objective-C) 类,因为我不想手动发送 Objective-C 消息。但是,我主要使用 AppKit、IOKit 和 Foundation 等框架,extern (Objective-C) 需要静态链接才能根据documentation 工作。

但是,我不认为静态链接操作系统库是一个好主意。在考虑不同的 macOS 版本时,它似乎很脆弱。

所以我的问题是,

  1. 静态链接 Foundation 和 AppKit 真的是个坏主意吗?
  2. 如果是,那么是否可以使用 dlopen 动态加载 .framework 文件,然后将函数指针绑定到 extern (Objective-C) 类?

【问题讨论】:

  • 作为extern 的替代品,您或许可以考虑使用单例?
  • @skaak 这似乎与我的问题无关。 extern 是一种将链接器的名称修改从 D 更改为 Objective-C 的方法。
  • 是的,抱歉。我正在考虑通过某个地方的某个单例来完成与 Objective-C 的所有接口,但这并没有改变或帮助太大。
  • 文档中的静态链接要求在哪里?
  • @Willeke 从dlang.org/spec/objc_interface.html#frameworks 开始显示的所有示例都在编译时将框架传递给链接器。如果可以进行动态链接,则不会显示。

标签: objective-c linker d


【解决方案1】:
  1. 没有。我不认为这是一个问题,这是相对标准的做法。当然,您将无法在同一个二进制文件中同时为 macOS 和 iO 构建(例如),但这种情况很少见。如果您dlopen 框架,您可能会发现它们有时也会在 macOS 版本中移动。苹果不时地有其他方法来破坏你的向后兼容性,但删除你手下的框架并不常见。 您将成为 extern(Objective-C) 的首批幸运用户之一。

  2. 是的,这是绝对可能的。但是你必须直接与 ObjC 运行时对话,因为自 OSX 以来没有导出任何函数,只有类 ID。您必须为要调用的每个方法编写一些脆弱的代码。从协议继承是非常困难的。你真的不能那样做。从好的方面来说,它在 DMD 和 LDC 中的工作方式相同。您可以签入dplug:cocoa。我真的建议改用 extern(Objective-C) 和静态链接。

【讨论】:

  • 澄清一下,假设我在 Big Sur 上构建了一个带有静态链接的可执行文件并想要分发它。 Mojave 用户可以毫无问题地运行它吗?还是我必须为每个支持的 macOS 版本构建不同的可执行文件?
  • 如果您的 Universal Binary 2 中有 x86_64 版本,它将适用于 macOS 10.12
  • 框架不是静态链接的,它们是静态绑定的。操作系统只是在加载时使用这种样式为您打开它,您的应用程序中不包含库中的实际代码。
  • 哦,我应该补充一点,使用 extern(Objective-C),它甚至以这种方式提取的唯一符号是少数运行时加载程序。所以它加载一个运行时加载器来查找动态符号。它基于选择器名称而不是索引槽或类似的东西进行匹配,因此您只需要定义您需要的少数东西。它可能不是 100% 兼容,但应该非常接近。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-15
  • 1970-01-01
  • 2012-06-17
相关资源
最近更新 更多