1 个不稳定版本
使用旧的Rust 2015
| 0.0.0 | 2024年6月27日 |
|---|
#2 在 #objc2
2KB
Rust中的Objective-C
你可能感兴趣的crate是
objc2,它提供Rust和Objective-C之间的双向互操作性,包括在Rust中定义Objective-C类。objc2-*crates,它提供了自动生成的Apple Objective-C框架(例如AppKit、Foundation、Metal、WebKit等)接口。block2,它提供了Apple C blocks的绑定,Rust闭包的C等价物。
联系我们
随时可以在GitHub上创建一个问题。
如果你更喜欢同步的、不太正式的讨论,我们有一个Matrix工作区,你可以在"Users"房间中提出任何问题。
目标
在这样一个开源项目中,如性能、易用性、可理解性、可移植性等,有很多冲突的目标,但以下两个可以被视为本项目其他所有内容的指导原则。
1. 完整的稳定性
这些crate的非协商目标是要完全"稳定",这意味着它绝对不能让安全的Rust引发未定义行为!
截至2023年1月,我(@madsmtm)还没有找到一个单独的Rust crate或项目可以安全地调用Objective-C。我发现的问题包括
- 错误的方法调用ABI。
- 错误的内存管理(在最好的情况下,它们只是泄漏很多)。
- 不正确使用
&mut。 - 主线程不安全。
我这样说并不是要批评这些项目,这是完全可以理解的!Objective-C和Rust的语义差异很大,因此解决这些问题需要警惕和专注,例如,系统剪贴板库就做不到这一点!相反,我这样说是为了提供保证:Rust的无畏并发能力可以重新夺回!这个项目针对问题的处理方法是有效的,泄漏、段错误、竞争条件等问题可以完全消除!
不用说,没有什么是完美的,所以如果你认为你发现了一个可靠性漏洞,请不要犹豫,在问题跟踪器上报告它。已知的可靠性漏洞(无论理论如何)都记录在I-unsound标签中。
2. Rust的惯用法
如果我们只是将每个API标记为unsafe,那么可靠性就很容易实现了(这个方法的先行者objc基本上是可靠的)。然而,这只会将负担推给用户,我们并没有好多少!
因此,我们将尽量做到既安全又符合惯用法;使用引用而不是指针来表示对象及其可变性,使用Option而不是null,自动进行内存管理而不是手动管理,等等(参见关于“分层安全”的这些说明)。这些抽象应该是零成本的,但这当然是在易于使用和性能之间的一种权衡。
objc2和block2中的某些API仍然必须保持unsafe,因此这些包含详细的# 安全性部分,以便让您确切知道需要遵守哪些安全保证。框架库在这方面有点困难,因为它们主要是自动生成的,这意味着几乎没有什么可以默认为安全的!然而,我们仍然可以通过将手动审计的功能标记为安全来减轻这个问题(我们需要您的帮助)。
最低支持的Rust版本(MSRV)
当前最低支持的Rust版本是1.60;这并不是由政策决定的,所以它可能在任何补丁版本中随时改变。
请帮助我们#203中定义一个政策。
从objc及其家族迁移
如果您的项目规模相对较小,最简单的方法可能是直接跳到使用框架库来替换所有内容(当您这样做时,不要忘记在途中将您使用的unsafe方法标记为安全)。
如果您的项目规模较大,您可以考虑逐步升级,在每一步都查看变更日志。对于最常见的案例,变更日志将包括有关如何升级的有用示例。
例如,您首先可以在Cargo.toml中使用objc2而不是objc。
[dependencies]
objc = { package = "objc2", version = "0.2.7" }
之后,您可以升级到下一个版本,在本例中是 v0.3.0-alpha.0,并根据变更日志对您的代码进行必要的修改。以此类推,每个后续版本都是如此。
许可证
本项目采用MIT许可证授权,请参阅LICENSE.txt。
正在进行的工作是为了使其同时获得Apache许可证(版本2.0)的双重许可,请参阅此处。
致谢/先前艺术
此存储库是以下项目的合并,有关分叉原因请参阅此处
objc- 重命名为
objc2。
- 重命名为
objc-encode- 重命名为
objc2-encode。
- 重命名为
objc_exception- 已移动到
objc2::exception。
- 已移动到
objc_id- 已移动到
objc2::rc。
- 已移动到
objc-foundation- 重命名为
objc2-foundation。
- 重命名为
block- 重命名为
block2。
- 重命名为
这些几乎完全是由@SSheldon创建的,所以对他们在这些crate上的出色工作表示衷心的感谢!
此项目还受到了以下项目的启发
apple-syscacaocore-foundation-rs项目fruitymetalobjrsobjr及其家族rust-maciosuikit-sys和simlay的Objective-C工作(在bindgen中)cidre
最后,这绝对不是唯一尝试与Objective-C交互的项目;其他语言也这样做过(成功程度不同)
- Swift:从一开始就是为了Objective-C交互而构建的,并且是
objc2希望达到功能对等的目标(尽管可能永远无法实现)。真正设计精美的语言! - C#:Xamarin,Xamarin.Mac,这是“应该工作”的灵感来源。
- Python:PyObjC(以前?)官方Apple项目,与“BridgeSupport”一起工作,现在他们还通过调用Clang生成元数据。其他包括
objp和rubicon.objc。 - Ruby:MacRuby,RubyCocoa
- Dart:
ffigen - Kotlin:某种程度上内置支持
- Nim:某种程度上内置支持,
darwin,objc - D:某种程度上内置支持,
derelict - Java: Java-Objective-C-Bridge,Multi-OS Engine: Nat/J(还有生成器),苹果还有一个非常古老的官方项目。
- Node.js: NodObjC,
objc - Zig: zig-objcrt
- D:某种程度上内置支持,
derelict - V: 实际上并不存在,它们只是编写和编译Objective-C代码,并使用手动C绑定。
- Go: MacDriver